mirror of
https://github.com/ghndrx/prowler.git
synced 2026-02-10 23:05:05 +00:00
fix(security-hub): unique finding id, if status not changed, comment otherwise resolve older findings
This commit is contained in:
@@ -256,6 +256,7 @@ generateJsonAsffOutput(){
|
||||
|
||||
local severity=$3
|
||||
jq -M -c \
|
||||
--arg UUID $(uuidgen | awk '{print tolower($0)}') \
|
||||
--arg ACCOUNT_NUM "$ACCOUNT_NUM" \
|
||||
--arg TITLE_TEXT "$TITLE_TEXT" \
|
||||
--arg MESSAGE "$(echo -e "${message}" | sed -e 's/^[[:space:]]*//')" \
|
||||
@@ -269,15 +270,15 @@ generateJsonAsffOutput(){
|
||||
--arg TIMESTAMP "$(get_iso8601_timestamp)" \
|
||||
--arg PROWLER_VERSION "$PROWLER_VERSION" \
|
||||
--arg AWS_PARTITION "$AWS_PARTITION" \
|
||||
-n '{
|
||||
-n '{
|
||||
"SchemaVersion": "2018-10-08",
|
||||
"Id": "prowler-\($TITLE_ID)-\($ACCOUNT_NUM)-\($REPREGION)-\($UNIQUE_ID)",
|
||||
"Id": "arn:\($AWS_PARTITION):securityhub:\($REPREGION):\($ACCOUNT_NUM):product/prowler/\($PROWLER_VERSION)/finding/\($UUID)",
|
||||
"ProductArn": "arn:\($AWS_PARTITION):securityhub:\($REPREGION):\($ACCOUNT_NUM):product/\($ACCOUNT_NUM)/default",
|
||||
"ProductFields": {
|
||||
"ProviderName": "Prowler",
|
||||
"ProviderVersion": $PROWLER_VERSION
|
||||
},
|
||||
"GeneratorId": "prowler-\($PROWLER_VERSION)",
|
||||
"GeneratorId": "prowler-\($TITLE_ID)-\($ACCOUNT_NUM)-\($REPREGION)-\($UNIQUE_ID)",
|
||||
"AwsAccountId": $ACCOUNT_NUM,
|
||||
"Types": [
|
||||
$TYPE
|
||||
|
||||
@@ -28,15 +28,42 @@ checkSecurityHubCompatibility(){
|
||||
exit $EXITCODE
|
||||
fi
|
||||
done
|
||||
# Get unresolved findings
|
||||
SECURITY_HUB_PREVIOUS_FINDINGS=$($AWSCLI securityhub get-findings --filters '{"GeneratorId":[{"Value": "prowler-","Comparison":"PREFIX"}],"WorkflowStatus":[{"Value": "RESOLVED","Comparison":"NOT_EQUALS"}]}' | jq -r ".Findings[] | {Id, GeneratorId, Workflow, Compliance}"| jq -s)
|
||||
}
|
||||
|
||||
sendToSecurityHub(){
|
||||
local findings="$1"
|
||||
local region="$2"
|
||||
BATCH_IMPORT_RESULT=$($AWSCLI securityhub --region "$region" $PROFILE_OPT batch-import-findings --findings "${findings}")
|
||||
# A successful CLI response is: {"SuccessCount": 1,"FailedFindings": [],"FailedCount": 0}
|
||||
# Therefore, check that SuccessCount is indeed 1
|
||||
if [[ -z "${BATCH_IMPORT_RESULT}" ]] || ! jq -e '.SuccessCount == 1' <<< "${BATCH_IMPORT_RESULT}" > /dev/null 2>&1; then
|
||||
local generator_id=$(echo $findings | jq -r ".GeneratorId")
|
||||
local status=$(echo $findings | jq -r ".Compliance.Status")
|
||||
local product_arn=$(echo $findings | jq -r ".ProductArn")
|
||||
PREVIOUS_FINDING=$(echo $SECURITY_HUB_PREVIOUS_FINDINGS | jq --arg finding "$generator_id" '.[] | select((.GeneratorId==$finding))' | jq -cs)
|
||||
PREVIOUS_FINDING_IDS=$(echo $PREVIOUS_FINDING | jq -c --arg parn "$product_arn" 'map({"Id": .Id, ProductArn: $parn} )');
|
||||
if [[ $PREVIOUS_FINDING != "[]" ]]; then
|
||||
|
||||
SAME_STATUS=$(echo $PREVIOUS_FINDING | jq --arg status "$status" '.[] | select(.Compliance.Status!=$status)')
|
||||
SUPPRESSED=$(echo $PREVIOUS_FINDING | jq '.[] | select(.Workflow.Status=="SUPPRESSED")')
|
||||
# If are old non-resolved findings with different status, resolve them and import new one
|
||||
if [[ ! -z $SAME_STATUS && -z $SUPPRESSED ]]; then
|
||||
BATCH_UPDATE_RESULT=$($AWSCLI securityhub --region "$region" $PROFILE_OPT batch-update-findings --finding-identifiers "${PREVIOUS_FINDING_IDS}" --workflow '{"Status": "RESOLVED"}')
|
||||
BATCH_IMPORT_RESULT=$($AWSCLI securityhub --region "$region" $PROFILE_OPT batch-import-findings --findings "${findings}")
|
||||
else
|
||||
# Update to avoid being deleted
|
||||
BATCH_UPDATE_RESULT=$($AWSCLI securityhub --region "$region" $PROFILE_OPT batch-update-findings --finding-identifiers "${PREVIOUS_FINDING_IDS}" --note '{"Text": "Finding re-detected by Prowler scan", "UpdatedBy": "prowler"}')
|
||||
fi
|
||||
else
|
||||
#If new (or no unresolved ones) import it
|
||||
BATCH_IMPORT_RESULT=$($AWSCLI securityhub --region "$region" $PROFILE_OPT batch-import-findings --findings "${findings}")
|
||||
fi
|
||||
|
||||
# Check for success if updated
|
||||
if [[ ! -z "${BATCH_UPDATE_RESULT}" ]] && ! jq -e '.ProcessedFindings >= 1' <<< "${BATCH_UPDATE_RESULT}" > /dev/null 2>&1; then
|
||||
echo -e "\n$RED ERROR!$NORMAL Failed to update AWS Security Hub finding\n"
|
||||
fi
|
||||
|
||||
# Check for success if imported
|
||||
if [[ ! -z "${BATCH_IMPORT_RESULT}" ]] && ! jq -e '.SuccessCount == 1' <<< "${BATCH_IMPORT_RESULT}" > /dev/null 2>&1; then
|
||||
echo -e "\n$RED ERROR!$NORMAL Failed to send check output to AWS Security Hub\n"
|
||||
fi
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user