refactor(Prowler): Main logic refactor (#1189)

* fix(aws_profile_loader): New functions

* fix(shellcheck): Temporary remove Shellcheck

* fix(aws_cli_detector): new function

* fix(jq_detector): New function

* fix(os_detector): New function

* fix(output_bucket): Output bucket input check in main

* fix(python_detector): deleted unused python detector

* fix(credentials): credentials check out of whoami

* [break]refactor(main)

* [BREAK] Get list of checks parsing all input options

* [break]refactor(main): execute checks functions

* [break]refactor(main): move functions to libs

* fix(validations): custom check validation and typos

* refactor(validate_options): Include comments

* fix(custom_checks): Minor fixes

* refactor(closing_files): include libraries

* refactor(loader): Include ignored checks

* refactor(main): Fix shellcheck

* refactor(loader): beautify

* refactor(monochrome): without variables

* refactor(modes): MODES array not needed

* refactor(whoami): get error from AWSCLI

* refactor(secrets-detector)

* refactor(secrets-detector)

* fix(html_scoring): html scoring was fixed.

* fix(load_checks_from_file)

* fix(color-code): Print if not mono

* fix(not extra): Fixed if EXCLUDE_CHECK_ID is empty

* fix(IFS): Restore default IFS once modes are parsed

* fix(bucket): validate before whoami

* fix(bucket): validate before whoami

Co-authored-by: n4ch04 <nachor1992@gmail.com>
Co-authored-by: sergargar <sergio@verica.io>
Co-authored-by: Nacho Rivera <59198746+n4ch04@users.noreply.github.com>
This commit is contained in:
Pepe Fagoaga
2022-06-13 17:34:31 +02:00
committed by GitHub
co-authored by n4ch04 sergargar Nacho Rivera
parent 74a9b42d9f
commit da000b54ca
51 changed files with 1120 additions and 1048 deletions
+43 -25
View File
@@ -45,7 +45,6 @@ EXTENSION_TEXT="txt"
EXTENSION_HTML="html"
HTML_LOGO_URL="https://github.com/prowler-cloud/prowler/"
HTML_LOGO_IMG="https://github.com/prowler-cloud/prowler/raw/master/util/html/prowler-logo-new.png"
TIMESTAMP=$(get_iso8601_timestamp)
PROWLER_PARAMETERS=$@
@@ -65,19 +64,29 @@ set_exitcode () {
# Add header to certain output files readed from mode
output_files_init() {
for MODE in "${MODES[@]}";
OIFS="${IFS}"
IFS=','
for MODE_TYPE in ${MODE}
do
if [ "${MODE}" == 'html' ]
if [ "${MODE_TYPE}" == 'html' ]
then
addHtmlHeader
HTML_REPORT_INIT="1"
export HTML_REPORT_INIT
fi
if [ "${MODE}" == 'csv' ]
if [ "${MODE_TYPE}" == 'csv' ]
then
printCsvHeader
fi
done
IFS="${OIFS}"
}
# Close HTML output file
output_files_end() {
if [[ "${MODE}" =~ "html" ]]; then
addHtmlFooter >> "${OUTPUT_FILE_NAME}.${EXTENSION_HTML}"
fi
}
# Check if resource checked is allowlisted
@@ -91,7 +100,7 @@ allowlist_check() {
# IGNORE_CHECK_NAME is the check with resources allowlisted
# RESOURCE_VALUE is what it comes after 'CHECK_NAME:'
IGNORE_CHECK_NAME=$(awk -F ":" '{print $1}' <<< "${excluded_item}")
RESOURCE_VALUE=$(awk -F "${CHECK_NAME}:" '{print $2}' <<< "${excluded_item}")
RESOURCE_VALUE=$(awk -F "${CHECK_NAME}:" '{print $2}' <<< "${excluded_item}")
if [[ "${IGNORE_CHECK_NAME}" == "${CHECK_NAME}" ]]
then
if [[ "${CHECKED_VALUE}" =~ ${RESOURCE_VALUE} ]]
@@ -100,7 +109,7 @@ allowlist_check() {
break
fi
fi
done <<< "$IGNORES"
echo "${CHECK_RESULT}"
}
@@ -140,23 +149,26 @@ general_output() {
REGION_FROM_CHECK=$REGION
fi
# Iterating over input modes
for MODE in "${MODES[@]}";
OIFS="${IFS}"
IFS=','
for MODE_TYPE in ${MODE}
do
if [ "${MODE}" == 'html' ]
IFS="${OIFS}"
if [ "${MODE_TYPE}" == 'html' ]
then
generateHtmlOutput "${CHECK_RESULT_EXTENDED}" "${CHECK_RESULT}"
elif [ "${MODE}" == 'csv' ]
elif [ "${MODE_TYPE}" == 'csv' ]
then
echo "${CSV_LINE}" >> "${OUTPUT_FILE_NAME}"."${EXTENSION_CSV}"
elif [ "${MODE}" == 'json' ]
elif [ "${MODE_TYPE}" == 'json' ]
then
generateJsonOutput "${CHECK_RESULT_EXTENDED}" "${CHECK_RESULT}" "$CHECK_RESOURCE_ID" >> "${OUTPUT_FILE_NAME}"."${EXTENSION_JSON}"
elif [ "${MODE}" == 'json-asff' ]
elif [ "${MODE_TYPE}" == 'json-asff' ]
then
JSON_ASFF_OUTPUT=$(generateJsonAsffOutput "${CHECK_RESULT_EXTENDED}" "PASSED" "$CHECK_RESOURCE_ID")
echo "${JSON_ASFF_OUTPUT}" >> "${OUTPUT_FILE_NAME}"."${EXTENSION_ASFF}"
if [[ "${SEND_TO_SECURITY_HUB}" -eq 1 ]]; then
sendToSecurityHub "${JSON_ASFF_OUTPUT}" "${REGION_FROM_CHECK}"
sendToSecurityHub "${JSON_ASFF_OUTPUT}" "${REGION_FROM_CHECK}"
fi
elif is_junit_output_enabled
then
@@ -164,7 +176,7 @@ general_output() {
then
output_junit_success "${CHECK_RESULT_EXTENDED}"
elif [ "${CHECK_RESULT}" == 'INFO' ]
then
then
output_junit_info "${CHECK_RESULT_EXTENDED}"
elif [ "${CHECK_RESULT}" == 'FAIL' ]
then
@@ -173,7 +185,7 @@ general_output() {
then
output_junit_skipped "${CHECK_RESULT_EXTENDED}"
fi
elif [ "${MODE}" == 'mono' ]
elif [ "${MODE_TYPE}" == 'mono' ]
then
echo " $COLOR_CODE ${CHECK_RESULT}! $NORMAL ${CHECK_RESULT_EXTENDED}">> "${OUTPUT_FILE_NAME}"."${EXTENSION_TEXT}"
fi
@@ -195,11 +207,13 @@ textPass(){
CHECK_RESOURCE_ID="${3}"
CHECK_REGION="${2}"
PASS_COUNTER=$((PASS_COUNTER+1))
if is_quiet "${QUIET}"
then
return
fi
general_output "${CHECK_RESULT}" "${CHECK_RESULT_EXTENDED}" "${CHECK_RESOURCE_ID}" "${CHECK_REGION}"
}
@@ -218,15 +232,17 @@ textInfo(){
}
textFail(){
CHECK_RESULT='FAIL'
CHECK_RESULT_EXTENDED="${1}"
CHECK_RESOURCE_ID="${3}"
CHECK_REGION="${2}"
FAIL_COUNTER=$((FAIL_COUNTER+1))
# Check if resources are whitelisted
CHECK_RESULT=$(allowlist_check "${CHECK_RESULT_EXTENDED}")
# only set non-0 exit code on FAIL mode, WARN is ok
if [[ "${CHECK_RESULT}" == "FAIL" ]]
then
@@ -237,11 +253,13 @@ textFail(){
}
textTitle(){
TITLE_ID="${1}"
TITLE_TEXT="${2}"
CHECK_ASFF_COMP_TYPE="${6}"
CHECK_ASFF_COMP_TYPE="${6}"
CHECKS_COUNTER=$((CHECKS_COUNTER+1))
if [[ $NUMERAL ]]; then
# Left-pad the check ID with zeros to simplify sorting, e.g. 1.1 -> 1.01
TITLE_ID=$(awk -F'.' '{ printf "%d.%02d", $1, $2 }' <<< "$TITLE_ID")
@@ -257,7 +275,7 @@ textTitle(){
SUPPORT) ITEM_CIS_LEVEL="Support";;
*) ITEM_CIS_LEVEL="Unspecified or Invalid";;
esac
echo -e "$TITLE_ID $TITLE_TEXT - $CHECK_SERVICENAME $CHECK_SEVERITY"
}
@@ -321,14 +339,14 @@ generateJsonAsffOutput(){
# Replace any successive non-conforming characters with a single underscore
local message=$1
local status=$2
#Checks to determine if the rule passes in a resource name that prowler uses to track the AWS Resource for allowlisting purposes
if [[ -z $3 ]]; then
local resource_id="NONE_PROVIDED"
else
local resource_id=$3
fi
if [[ "$status" == "FAIL" ]]; then
status="FAILED"
fi
@@ -384,7 +402,7 @@ generateJsonAsffOutput(){
"Status": $STATUS,
"RelatedRequirements": [ $COMPLIANCE_RELATED_REQUIREMENTS ]
}
}'
}
@@ -404,7 +422,7 @@ generateHtmlOutput(){
if [[ $status == "WARN" ]];then
local ROW_CLASS='table-warning'
fi
local CHECK_SEVERITY="$(echo $CHECK_SEVERITY | sed 's/[][]//g')"
echo '<tr class="'$ROW_CLASS'">' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
@@ -425,4 +443,4 @@ generateHtmlOutput(){
echo ' <td>'$CHECK_RESOURCE_ID'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '</tr>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
}
}