kics
kics copied to clipboard
"Passwords And Secrets - Generic Secret" False Positive Results
CASE 1
Actual Behavior
A false positive result is detected in line 76 ( SLACK_SIGNING_SECRET = "projects/455826092000/secrets/SlackSigningSecret/versions/latest"
). The result is flagging a path to a secret, which is not a True Positive.
Steps to Reproduce the Problem
docker run -v /path/folder:/path checkmarx/kics:v1.6.1 scan -p /path/sample.json
Sample to reproduce the problem:
locals {
project = "larkworthy-tester"
project_number = "455826092000"
location = "EU"
region = "europe-west1"
base_image_name = "openresty/openresty"
base_image_tag = "1.15.8.3-alpine"
upstream_url = "https://camunda-secure-flxotk3pnq-ew.a.run.app"
authorized_domain = "futurice.com"
# You need to provision this manually at https://console.developers.google.com/apis/credentials
# We are building a Web Application and do not need the client_secret
oauth_client_id = "455826092000-oi4h9ul0b943oi8f8in89pnjiroj1d4u.apps.googleusercontent.com"
# Chicken and egg: You can only figure this out after deploying once!
service_url = "https://openresty-flxotk3pnq-ew.a.run.app"
}
terraform {
backend "gcs" {
prefix = "openresty/state"
bucket = "terraform-larkworthy"
}
}
provider "google" {
project = local.project
region = local.region
}
# Create service account to run service
resource "google_service_account" "openresty" {
account_id = "openresty"
display_name = "openresty"
}
resource "google_project_iam_member" "openresty_invoker" {
project = local.project
role = "roles/run.invoker"
member = "serviceAccount:${google_service_account.openresty.email}"
}
resource "google_project_iam_member" "openresty_publisher" {
project = local.project
role = "roles/pubsub.publisher"
member = "serviceAccount:${google_service_account.openresty.email}"
}
resource "google_project_iam_member" "openresty_subscriber" {
project = local.project
role = "roles/pubsub.subscriber"
member = "serviceAccount:${google_service_account.openresty.email}"
}
# Policy to allow public access to Cloud Run endpoint
data "google_iam_policy" "noauth" {
binding {
role = "roles/run.invoker"
members = ["allUsers"]
}
}
# Allow public access to ORY openresty
resource "google_cloud_run_service_iam_policy" "noauth" {
location = google_cloud_run_service.openresty.location
project = google_cloud_run_service.openresty.project
service = google_cloud_run_service.openresty.name
policy_data = data.google_iam_policy.noauth.policy_data
}
# Hydrate config into .build directory
resource "local_file" "config" {
content = templatefile("${path.module}/files/default.template.conf", {
OAUTH_CLIENT_ID = local.oauth_client_id
UPSTREAM_URL = local.upstream_url
AUTHORIZED_DOMAIN = local.authorized_domain
WAL_TOPIC = google_pubsub_topic.httpwal.id
SLACK_SIGNING_SECRET = "projects/455826092000/secrets/SlackSigningSecret/versions/latest"
AUTHORIZED_WAL_USER = google_service_account.openresty.email
})
filename = "${path.module}/.build/default.conf"
}
# Hydrate login into .build directory
resource "local_file" "login" {
content = templatefile("${path.module}/files/login.template", {
OAUTH_CLIENT_ID = local.oauth_client_id
})
filename = "${path.module}/.build/login"
}
# Copy files into .build directory
resource "template_dir" "swiss" {
source_dir = "${path.module}/files/swiss"
destination_dir = "${path.module}/.build/swiss"
}
# Create a zip just to generate a sha
data "archive_file" "swiss" {
type = "zip"
source_dir = "${path.module}/.build/swiss"
output_path = "/tmp/swiss.zip"
}
# Cloud Run Openresty
resource "google_cloud_run_service" "openresty" {
name = "openresty"
location = local.region
template {
spec {
# Use locked down Service Account
service_account_name = google_service_account.openresty.email
containers {
image = null_resource.openresty_image.triggers.image
}
}
}
traffic {
percent = 100
latest_revision = true
}
}
resource "google_pubsub_topic" "httpwal" {
name = "openresty_wal"
}
# grant Cloud Pub/Sub the permission to create tokens for authenticating the subscription
resource "google_project_iam_member" "pubsub_token_creator" {
project = local.project
role = "roles/iam.serviceAccountTokenCreator"
member = "serviceAccount:service-${local.project_number}@gcp-sa-pubsub.iam.gserviceaccount.com"
}
resource "google_pubsub_subscription" "httpwal" {
name = "httpwal"
topic = google_pubsub_topic.httpwal.name
ack_deadline_seconds = 120
push_config {
push_endpoint = "${local.service_url}/wal-playback/"
oidc_token {
service_account_email = google_service_account.openresty.email
}
attributes = {
x-goog-version = "v1"
}
}
}
CASE 2
Actual Behavior
A false positive result is detected in line 24 ( Description: 'Used to create resource-based authorization policy for "secretsmanager:GetSecretValue" action. E.g. All Athena JDBC Federation secret names can be prefixed with "AthenaJdbcFederation" and authorization policy will allow "arn:${AWS::Partition}:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:AthenaJdbcFederation*". Parameter value in this case should be "AthenaJdbcFederation". If you do not have a prefix, you can manually update the IAM policy to add allow any secret names.'
). The result is flagging a description block, which is not a True Positive.
Steps to Reproduce the Problem
docker run -v /path/folder:/path checkmarx/kics:v1.6.1 scan -p /path/sample.json
Sample to reproduce the problem:
Transform: 'AWS::Serverless-2016-10-31'
Metadata:
'AWS::ServerlessRepo::Application':
Name: AthenaJdbcConnector
Description: 'This connector enables Amazon Athena to communicate with your Database instance(s) using JDBC driver.'
Author: 'default author'
SpdxLicenseId: Apache-2.0
LicenseUrl: LICENSE.txt
ReadmeUrl: README.md
Labels:
- athena-federation
HomePageUrl: 'https://github.com/awslabs/aws-athena-query-federation'
SemanticVersion: 2021.41.1
SourceCodeUrl: 'https://github.com/awslabs/aws-athena-query-federation'
Parameters:
LambdaFunctionName:
Description: 'The name you will give to this catalog in Athena. It will also be used as the function name. This name must satisfy the pattern ^[a-z0-9-_]{1,64}$'
Type: String
AllowedPattern: ^[a-z0-9-_]{1,64}$
DefaultConnectionString:
Description: 'The default connection string is used when catalog is "lambda:${LambdaFunctionName}". Catalog specific Connection Strings can be added later. Format: ${DatabaseType}://${NativeJdbcConnectionString}.'
Type: String
SecretNamePrefix:
Description: 'Used to create resource-based authorization policy for "secretsmanager:GetSecretValue" action. E.g. All Athena JDBC Federation secret names can be prefixed with "AthenaJdbcFederation" and authorization policy will allow "arn:${AWS::Partition}:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:AthenaJdbcFederation*". Parameter value in this case should be "AthenaJdbcFederation". If you do not have a prefix, you can manually update the IAM policy to add allow any secret names.'
Type: String
SpillBucket:
Description: 'The name of the bucket where this function can spill data.'
Type: String
SpillPrefix:
Description: 'The prefix within SpillBucket where this function can spill data.'
Type: String
Default: athena-spill
LambdaTimeout:
Description: 'Maximum Lambda invocation runtime in seconds. (min 1 - 900 max)'
Default: 900
Type: Number
LambdaMemory:
Description: 'Lambda memory in MB (min 128 - 3008 max).'
Default: 3008
Type: Number
DisableSpillEncryption:
Description: 'If set to ''false'' data spilled to S3 is encrypted with AES GCM'
Default: 'false'
Type: String
SecurityGroupIds:
Description: 'One or more SecurityGroup IDs corresponding to the SecurityGroup that should be applied to the Lambda function. (e.g. sg1,sg2,sg3)'
Type: 'List<AWS::EC2::SecurityGroup::Id>'
SubnetIds:
Description: 'One or more Subnet IDs corresponding to the Subnet that the Lambda function can use to access you data source. (e.g. subnet1,subnet2)'
Type: 'List<AWS::EC2::Subnet::Id>'
Resources:
JdbcConnectorConfig:
Type: 'AWS::Serverless::Function'
Properties:
Environment:
Variables:
disable_spill_encryption: !Ref DisableSpillEncryption
spill_bucket: !Ref SpillBucket
spill_prefix: !Ref SpillPrefix
default: !Ref DefaultConnectionString
FunctionName: !Ref LambdaFunctionName
Handler: "com.amazonaws.athena.connectors.jdbc.MultiplexingJdbcCompositeHandler"
CodeUri: "./target/athena-jdbc-2021.41.1.jar"
Description: "Enables Amazon Athena to communicate with Databases using JDBC"
Runtime: java8
Timeout: !Ref LambdaTimeout
MemorySize: !Ref LambdaMemory
Policies:
- Statement:
- Action:
- secretsmanager:GetSecretValue
Effect: Allow
Resource: !Sub 'arn:${AWS::Partition}:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:${SecretNamePrefix}*'
Version: '2012-10-17'
- Statement:
- Action:
- logs:CreateLogGroup
Effect: Allow
Resource: !Sub 'arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:*'
Version: '2012-10-17'
- Statement:
- Action:
- logs:CreateLogStream
- logs:PutLogEvents
Effect: Allow
Resource: !Sub 'arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${LambdaFunctionName}:*'
Version: '2012-10-17'
- Statement:
- Action:
- athena:GetQueryExecution
- s3:ListAllMyBuckets
Effect: Allow
Resource: '*'
Version: '2012-10-17'
#S3CrudPolicy allows our connector to spill large responses to S3. You can optionally replace this pre-made policy
#with one that is more restrictive and can only 'put' but not read,delete, or overwrite files.
- S3CrudPolicy:
BucketName: !Ref SpillBucket
#VPCAccessPolicy allows our connector to run in a VPC so that it can access your data source.
- VPCAccessPolicy: {}
VpcConfig:
SecurityGroupIds: !Ref SecurityGroupIds
SubnetIds: !Ref SubnetIds