Prowler is a security auditing tool for AWS that helps us catch security defects such as credentials stored in plain text or S3 buckets that are publically accessible by accident. While Prowler is generally a very useful technology it sometimes also reports false positives. Thankfully, Prowler also comes with a whitelisting functionality that allows us to ignore certain resources.
Planting a false positive
Let’s first plant a false positive. A simple example of a false positive that will be reported by Prowler is a Lambda environment variable that stores a Secret Manager ARN.
Prowler will find and report this as a potentially exposed secret as we can see below.
docker pull toniblyx/prowler
$ docker run -it \
$ --rm \
--name prowler \
--env AWS_ACCESS_KEY_ID \
--env AWS_SECRET_ACCESS_KEY \
toniblyx/prowler:latest -r eu-central-1 -c extra759
_
_ __ _ __ _____ _| | ___ _ __
| '_ \| '__/ _ \ \ /\ / / |/ _ \ '__|
| |_) | | | (_) \ V V /| | __/ |
| .__/|_| \___/ \_/\_/ |_|\___|_|v2.10.0-25May2022
|_| the handy cloud security tool
Date: Sun Jun 26 20:54:51 UTC 2022
Color code for results:
- INFO (Information)
- PASS (Recommended value)
- WARNING (Ignored by allowlist)
- FAIL (Fix required)
This report is being generated using the credentials below:
AWS-CLI Profile: [] AWS API Region: [eu-central-1] AWS Filter Region: [all]
AWS Account: [174394581677] UserId: [174394581677]
Caller Identity ARN: [arn:aws:iam::174394581677:root]
7.59 [extra759] Find secrets in Lambda functions variables - lambda [Critical]
INFO! eu-north-1: No Lambda functions found
INFO! ap-south-1: No Lambda functions found
INFO! eu-west-3: No Lambda functions found
INFO! eu-west-2: No Lambda functions found
INFO! eu-west-1: No Lambda functions found
INFO! ap-northeast-3: No Lambda functions found
INFO! ap-northeast-2: No Lambda functions found
INFO! ap-northeast-1: No Lambda functions found
INFO! sa-east-1: No Lambda functions found
INFO! ca-central-1: No Lambda functions found
INFO! ap-southeast-1: No Lambda functions found
INFO! ap-southeast-2: No Lambda functions found
FAIL! eu-central-1: Potential secret found in Lambda function my-little-lambda variables
INFO! us-east-1: No Lambda functions found
INFO! us-east-2: No Lambda functions found
INFO! us-west-1: No Lambda functions found
INFO! us-west-2: No Lambda functions found
Note the line
FAIL! eu-central-1: Potential secret found in Lambda function my-little-lambda variables
More specifically, the false positive will be reported by the check extra759 which was selected for the Prowler run with -c extra759
to speed up execution.
Note that prowler requires AWS credentials to run checks. I’m using my admin account’s credentials for this example. If you use Prowler in production, you will want to configure a dedicated user with the IAM auditing policies
- arn:aws:iam::aws:policy/SecurityAudit and
- arn:aws:iam::aws:policy/job-function/ViewOnlyAccess
Prowler, y u do dis?
Prowler reports a finding because its check extra759 simply exports a temporary file with all environment variables of our Lambda and then runs IBM’s detect-secrets tool on it (see check_extra759
and secrets-detector
for the mysterious inner workings).
The reason for detect-secrets
to report a defect is that it apparently considers a JSON object entry with a Secrets Manager ARN on the right side a secret keyword. We can see this by running git-secrets
on the environment variables export of the Lambda defined earlier. I.e. we run
aws lambda --region eu-central-1 get-function-configuration --function-name my-little-lambda --query 'Environment.Variables' --output json > /tmp/lambda-variables.json $
to get a JSON export of our Lambda’s environment variables. The JSON file, in this case, looks like this:
cat /tmp/lambda-variables.json
$ {
"FOO": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:foo"
}
If we run detect-secrets scan
on this file, we get the following output that tells us a secret keyword was found in line 2 (the finding is listed in results."/tmp/lambda-variables.json"
).
detect-secrets scan /tmp/lambda-variables.json
$ {
"exclude": {
"files": null,
"lines": null
},
"generated_at": "2022-06-27T05:29:31Z",
"plugins_used": [
{"name": "AWSKeyDetector"
},
{"name": "ArtifactoryDetector"
},
{"name": "AzureStorageKeyDetector"
},
{"base64_limit": 4.5,
"name": "Base64HighEntropyString"
},
{"name": "BasicAuthDetector"
},
{"name": "BoxDetector"
},
{"name": "CloudantDetector"
},
{"ghe_instance": "github.ibm.com",
"name": "GheDetector"
},
{"name": "GitHubTokenDetector"
},
{"hex_limit": 3,
"name": "HexHighEntropyString"
},
{"name": "IbmCloudIamDetector"
},
{"name": "IbmCosHmacDetector"
},
{"name": "JwtTokenDetector"
},
{"keyword_exclude": null,
"name": "KeywordDetector"
},
{"name": "MailchimpDetector"
},
{"name": "NpmDetector"
},
{"name": "PrivateKeyDetector"
},
{"name": "SlackDetector"
},
{"name": "SoftlayerDetector"
},
{"name": "SquareOAuthDetector"
},
{"name": "StripeDetector"
},
{"name": "TwilioKeyDetector"
}
],"results": {
"/tmp/lambda-variables.json": [
{"hashed_secret": "3c4c43b8cb2d7bbdba2ea6fd268e70483ef2235f",
"is_verified": false,
"line_number": 2,
"type": "Secret Keyword",
"verified_result": null
}
]
},"version": "0.13.1+ibm.50.dss",
"word_list": {
"file": null,
"hash": null
} }
Excluding Prowler false positives with an allow list
This is obviously not great since we’d preferably only want to get reports for true defects. Luckily, Prowler gives us the option to whitelist some resources using something called an allowlist. Documentation is a bit sparse, but with some experimentation, it’s easy to verify that entries of the form
<check-id>:<resource-name>
will be converted from errors to warnings.
For example, let’s allowlist our Lambda’s environment by defining an allowlist file /tmp/allowlist.txt
with the following content.
extra759:my-little-lambda
If we pass this file to Prowler and using the -w
option and run check extra759 again, we get the following report:
cat <<EOF > /tmp/allowlist.txt
$
extra759:my-little-lambda
EOF
$ docker run -it \
--rm \
--name prowler \
--env AWS_ACCESS_KEY_ID \
--env AWS_SECRET_ACCESS_KEY \type=bind,source="/tmp/allowlist.txt",target=/tmp/allowlist.txt \
--mount toniblyx/prowler:latest -r eu-central-1 -c extra759 -w /tmp/allowlist.txt
_
_ __ _ __ _____ _| | ___ _ __
| '_ \| '__/ _ \ \ /\ / / |/ _ \ '__|
| |_) | | | (_) \ V V /| | __/ |
| .__/|_| \___/ \_/\_/ |_|\___|_|v2.10.0-25May2022the handy cloud security tool
|_|
Date: Mon Jun 27 06:06:36 UTC 2022
Color code for results:
- INFO (Information)
- PASS (Recommended value)
- WARNING (Ignored by allowlist)
- FAIL (Fix required)
This report is being generated using credentials below:
eu-central-1] AWS Filter Region: [all]
AWS-CLI Profile: [] AWS API Region: [174394581677] UserId: [174394581677]
AWS Account: [
Caller Identity ARN: [arn:aws:iam::174394581677:root]
Getting allowlist from input file /tmp/allowlist.txt ...
Success! Allowlist was downloaded, starting Prowler...7.59 [extra759] Find secrets in Lambda functions variables - lambda [Critical]
INFO! eu-north-1: No Lambda functions found
INFO! ap-south-1: No Lambda functions found
INFO! eu-west-3: No Lambda functions found
INFO! eu-west-2: No Lambda functions found
INFO! eu-west-1: No Lambda functions found
INFO! ap-northeast-3: No Lambda functions found
INFO! ap-northeast-2: No Lambda functions found
INFO! ap-northeast-1: No Lambda functions found
INFO! sa-east-1: No Lambda functions found
INFO! ca-central-1: No Lambda functions found
INFO! ap-southeast-1: No Lambda functions found
INFO! ap-southeast-2: No Lambda functions found
WARNING! eu-central-1: Potential secret found in Lambda function my-little-lambda variables
INFO! us-east-1: No Lambda functions found
INFO! us-east-2: No Lambda functions found
INFO! us-west-1: No Lambda functions found INFO! us-west-2: No Lambda functions found
Prowler now prints the line
WARNING! eu-central-1: Potential secret found in Lambda function my-little-lambda variables
instead of reporting a failed check. So, as expected, the security warning for our false positive has been converted to a warning.