Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(dynamodb_allowlist): Support DynamoDB tables ARN for allowlist input #1118

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
- [Advanced Usage](#advanced-usage)
- [Security Hub integration](#security-hub-integration)
- [CodeBuild deployment](#codebuild-deployment)
- [Allowlist or remove FAIL from resources](#allowlist-or-allowlist-or-remove-a-fail-from-resources)
- [Allowlist](#allowlist-or-remove-a-fail-from-resources)
- [Fix](#how-to-fix-every-fail)
- [Troubleshooting](#troubleshooting)
- [Extras](#extras)
Expand Down Expand Up @@ -495,6 +495,15 @@ Sometimes you may find resources that are intentionally configured in a certain
S3 URIs are also supported as allowlist file, e.g. `s3://bucket/prefix/allowlist_sample.txt`
>Make sure that the used credentials have s3:GetObject permissions in the S3 path where the allowlist file is located.

DynamoDB table ARNs are also supported as allowlist file, e.g. `arn:aws:dynamodb:us-east-1:111111222222:table/allowlist`
>Make sure that the table has `account_id` as partition key and `rule` as sort key, and that the used credentials have dynamodb:Scan permissions in the table.
><p align="left"><img src="https://user-images.githubusercontent.com/38561120/165769502-296f9075-7cc8-445e-8158-4b21804bfe7e.png" alt="image" width="397" height="252" /></p>

>The field `account_id` can contains either an account ID or an `*` (which applies to all the accounts that use this table as a whitelist). As in the traditional allowlist file, the `rule` field must contain `checkID:resourcename` pattern.
><p><img src="https://user-images.githubusercontent.com/38561120/165770610-ed5c2764-7538-44c2-9195-bcfdecc4ef9b.png" alt="image" width="394" /></p>



Allowlist option works along with other options and adds a `WARNING` instead of `INFO`, `PASS` or `FAIL` to any output format except for `json-asff`.

## How to fix every FAIL
Expand Down
83 changes: 61 additions & 22 deletions include/allowlist
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,71 @@
# specific language governing permissions and limitations under the License.

allowlist(){
# check if the file is an S3 URI
if grep -q -E "^s3://([^/]+)/(.*?([^/]+))$" <<< "$ALLOWLIST_FILE"; then
# download s3 object
local S3_ALLOWLIST_FILE=allowlist_s3_file.txt
echo -e "$NOTICE Downloading allowlist from S3 URI $ALLOWLIST_FILE ..."
if ! $AWSCLI s3 cp $ALLOWLIST_FILE $S3_ALLOWLIST_FILE $PROFILE_OPT > /dev/null 2>&1; then
echo "$BAD FAIL! Access Denied trying to download allowlist from the S3 URI, please make sure it is correct and/or you have permissions to get the S3 object.$NORMAL"
# Check if the file is an S3 URI
if grep -q -E "^s3://([^/]+)/(.*?([^/]+))$" <<< "${ALLOWLIST_FILE}"; then
allowlist_S3
# Check if the file is a DynamoDB ARN
elif grep -q -E "^arn:aws:dynamodb:\w+(?:-\w+)+:\d{12}:table\/[A-Za-z0-9]+$" <<< "${ALLOWLIST_FILE}"; then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔝

allowlist_DynamoDB
else
# Check if the file is a DynamoDB ARN
allowlist_Textfile
fi
}

allowlist_S3() {
# download s3 object
local S3_ALLOWLIST_FILE=allowlist_s3_file.txt
echo -e "${NOTICE} Downloading allowlist from S3 URI ${ALLOWLIST_FILE} ...${NORMAL}"
if ! "${AWSCLI}" s3 cp "${ALLOWLIST_FILE}" "${S3_ALLOWLIST_FILE}" ${PROFILE_OPT} > /dev/null 2>&1; then
echo "${BAD} FAIL! Access Denied trying to download allowlist from the S3 URI, please make sure it is correct and/or you have permissions to get the S3 object.${NORMAL}"
EXITCODE=1
exit "${EXITCODE}"
fi
echo -e "${OK} Success! Allowlist was downloaded, starting Prowler...${NORMAL}"
# ignore lines starting with # (comments)
# ignore inline comments: check1:foo # inline comment
ALLOWLIST=$(awk '!/^[[:space:]]*#/{print }' <(cat "${S3_ALLOWLIST_FILE}") | sed 's/[[:space:]]*#.*$//g')
# remove temporary file
rm -f "${S3_ALLOWLIST_FILE}"
}

allowlist_DynamoDB() {
echo -e "${NOTICE} Getting allowlist from DynamoDB table ${ALLOWLIST_FILE} ...${NORMAL}"
DYNAMO_REGION=$(cut -d ":" -f 4 <<< "${ALLOWLIST_FILE}")
DYNAMO_TABLE=$(cut -d "/" -f 2 <<< "${ALLOWLIST_FILE}")
DYNAMO_ITEMS=$(${AWSCLI} dynamodb execute-statement --statement "SELECT rule FROM ${DYNAMO_TABLE} WHERE account_id=""'""${ACCOUNT_NUM}""'"" or account_id='*'" ${PROFILE_OPT} --region ${DYNAMO_REGION} --output json 2>&1 )
if grep -q -E 'AccessDenied|UnauthorizedOperation|ResourceNotFoundException' <<< "${DYNAMO_ITEMS}"; then
echo "${BAD} FAIL! Access Denied trying to get allowlist from the DynamoDB, please make sure it is correct and/or you have permissions to scan the table ${DYNAMO_TABLE}.${NORMAL}"
EXITCODE=1
exit ${EXITCODE}
fi
if [[ $(jq '."Items" | length' <<< "${DYNAMO_ITEMS}") -eq 0 ]]; then
echo "${NOTICE} No allowed resources were found for account ${ACCOUNT_NUM}, starting Prowler...${NORMAL}"
else
# Convert elements to allowlist file
ALLOWLIST=$(jq -r '.Items[].rule.S' <<< "${DYNAMO_ITEMS}")
if grep -q "null" <<< "${ALLOWLIST}"; then
echo "${BAD} FAIL! No rule key found in DynamoDB table, please make sure the table has rule as a sort key and account_id as the partition key...${NORMAL}"
EXITCODE=1
exit $EXITCODE
exit ${EXITCODE}
else
echo "${OK} Success! Allowed resources were added for account ${ACCOUNT_NUM}, starting Prowler...${NORMAL}"
fi
echo -e "$OK Success! Allowlist was downloaded, starting Prowler...$NORMAL"
fi
}

allowlist_Textfile() {
echo -e "${NOTICE} Getting allowlist from input file ${ALLOWLIST_FILE} ...${NORMAL}"
# Check if input allowlist file exists
if [[ -f "${ALLOWLIST_FILE}" ]]; then
# ignore lines starting with # (comments)
# ignore inline comments: check1:foo # inline comment
ALLOWLIST=$(awk '!/^[[:space:]]*#/{print }' <(cat "$S3_ALLOWLIST_FILE") | sed 's/[[:space:]]*#.*$//g')
# remove temporary file
rm -f "$S3_ALLOWLIST_FILE"
ALLOWLIST=$(awk '!/^[[:space:]]*#/{print }' <(cat "${ALLOWLIST_FILE}") | sed 's/[[:space:]]*#.*$//g')
echo -e "${OK} Success! Allowlist was downloaded, starting Prowler...${NORMAL}"
else
# Check if input allowlist file exists
if [[ -f "$ALLOWLIST_FILE" ]]; then
# ignore lines starting with # (comments)
# ignore inline comments: check1:foo # inline comment
ALLOWLIST=$(awk '!/^[[:space:]]*#/{print }' <(cat "$ALLOWLIST_FILE") | sed 's/[[:space:]]*#.*$//g')
else
echo "$BAD FAIL! $ALLOWLIST_FILE does not exist, please input a valid allowlist file.$NORMAL"
EXITCODE=1
exit $EXITCODE
fi
echo "${BAD} FAIL! ${ALLOWLIST_FILE} does not exist, please input a valid allowlist file.${NORMAL}"
EXITCODE=1
exit ${EXITCODE}
fi
}