@@ -13,16 +13,115 @@ GOSEC_RULES=${INPUT_GOSEC_RULES:-}
1313TRIVY_EXCLUDE_DIR=${INPUT_TRIVY_EXCLUDE_DIR:- }
1414TRIVY_RULES=${INPUT_TRIVY_RULES:- }
1515
16+ # Set output directory for temp files
17+ if [[ -n " $OUTPUT_DIR " ]]; then
18+ TEMP_OUTPUT_DIR=" $OUTPUT_DIR "
19+ else
20+ TEMP_OUTPUT_DIR=" $( pwd) "
21+ fi
22+
23+ # Run Trivy on Container Images if enabled
24+ if [[ " $INPUT_TRIVY_IMAGE_ENABLED " == " true" ]]; then
25+ echo " Running Trivy on Container Images"
26+ IFS=' ,' read -ra DOCKER_IMAGES <<< " ${INPUT_DOCKER_IMAGES}"
27+ for image in " ${DOCKER_IMAGES[@]} " ; do
28+ echo " Scanning image: $image "
29+ trivy image --scanners vuln --format json --output " $TEMP_OUTPUT_DIR /trivy_image_${image// \/ / _} .json" " $image " || :
30+ done
31+ fi
32+
33+ # Run Trivy on Dockerfiles if enabled
34+ if [[ " $INPUT_TRIVY_DOCKERFILE_ENABLED " == " true" ]]; then
35+ IFS=' ,' read -ra DOCKERFILES <<< " ${INPUT_DOCKERFILES}"
36+ for dockerfile in " ${DOCKERFILES[@]} " ; do
37+ echo " Scanning Dockerfile: $dockerfile "
38+ trivy config --format json --output " $TEMP_OUTPUT_DIR /trivy_dockerfile_${dockerfile// \/ / _} .json" " $GITHUB_WORKSPACE /$dockerfile " || :
39+ done
40+ fi
41+
42+ # Run Secret Scanning (Trufflehog) if enabled
43+ if [[ " $INPUT_SECRET_SCANNING_ENABLED " == " true" ]]; then
44+ echo " Running Secret Scanning with Trufflehog"
45+ trufflehog_cmd=" trufflehog filesystem "
46+ TRUFFLEHOG_EXCLUDE_FILE=$( mktemp)
47+ if [[ -n " $TRUFFLEHOG_EXCLUDE_DIR " ]]; then
48+ IFS=' ,' read -ra EXCLUDE_DIRS <<< " $TRUFFLEHOG_EXCLUDE_DIR"
49+ for dir in " ${EXCLUDE_DIRS[@]} " ; do
50+ echo " $dir " >> " $TRUFFLEHOG_EXCLUDE_FILE "
51+ done
52+ trufflehog_cmd+=" -x $TRUFFLEHOG_EXCLUDE_FILE "
53+ fi
54+ if [[ -n " $TRUFFLEHOG_RULES " ]]; then
55+ trufflehog_cmd+=" --rules $TRUFFLEHOG_RULES "
56+ fi
57+ trufflehog_cmd+=" --no-verification -j $GITHUB_WORKSPACE > $TEMP_OUTPUT_DIR /trufflehog_output.json"
58+ eval $trufflehog_cmd || :
59+ fi
1660
17- # Run ESLint (JavaScript SAST) if enabled
18- if [[ " ${INPUT_JAVASCRIPT_SAST_ENABLED:- false} " == " true" ]]; then
19- echo " Running ESLint"
20- ESLINT_EXCLUDE_DIR=${INPUT_ESLINT_EXCLUDE_DIR:- }
21- ESLINT_RULES=${INPUT_ESLINT_RULES:- }
61+ # POSIX-compatible file collection (replace mapfile)
62+ scan_files=()
63+ if [[ " $INPUT_SCAN_ALL " == " true" ]]; then
64+ while IFS= read -r file; do
65+ scan_files+=(" $file " )
66+ done < <( find . -type f \( -name ' *.py' -o -name ' *.go' -o -name ' *.js' -o -name ' *.jsx' -o -name ' *.ts' -o -name ' *.tsx' \) )
67+ elif [[ -n " $INPUT_SCAN_FILES " ]]; then
68+ IFS=' ,' read -ra scan_files <<< " $INPUT_SCAN_FILES"
69+ else
70+ if [[ -d .git ]]; then
71+ while IFS= read -r file; do
72+ scan_files+=(" $file " )
73+ done < <( git diff --name-only HEAD~1 HEAD)
74+ else
75+ while IFS= read -r file; do
76+ scan_files+=(" $file " )
77+ done < <( find . -type f \( -name ' *.py' -o -name ' *.go' -o -name ' *.js' -o -name ' *.jsx' -o -name ' *.ts' -o -name ' *.tsx' \) )
78+ fi
79+ fi
80+
81+ # Separate files by language
82+ python_files=()
83+ go_files=()
84+ js_files=()
85+ for file in " ${scan_files[@]} " ; do
86+ case " $file " in
87+ * .py) python_files+=(" $file " ) ;;
88+ * .go) go_files+=(" $file " ) ;;
89+ * .js|* .jsx|* .ts|* .tsx) js_files+=(" $file " ) ;;
90+ esac
91+ done
92+
93+ # Run Bandit on Python files
94+ if [[ " ${# python_files[@]} " -gt 0 && " $INPUT_PYTHON_SAST_ENABLED " == " true" ]]; then
95+ echo " Running Bandit on Python files: ${python_files[*]} "
96+ bandit_cmd=" bandit -f json -o $TEMP_OUTPUT_DIR /bandit_output.json ${python_files[*]} "
97+ if [[ -n " $BANDIT_EXCLUDE_DIR " ]]; then
98+ bandit_cmd+=" --exclude $BANDIT_EXCLUDE_DIR "
99+ fi
100+ if [[ -n " $BANDIT_RULES " ]]; then
101+ bandit_cmd+=" --skip $BANDIT_RULES "
102+ fi
103+ echo $bandit_cmd
104+ eval $bandit_cmd || :
105+ fi
22106
23- if [[ -z " $ESLINT_RULES " ]]; then
24- echo " Using default ESLint rules"
25- ESLINT_RULES=$( cat << 'EOF '
107+ # Run Gosec on Go files
108+ if [[ " ${# go_files[@]} " -gt 0 && " $INPUT_GOLANG_SAST_ENABLED " == " true" ]]; then
109+ echo " Running Gosec on Go files: ${go_files[*]} "
110+ gosec_cmd=" gosec -fmt json -out $TEMP_OUTPUT_DIR /gosec_output.json ${go_files[*]} "
111+ if [[ -n " $GOSEC_EXCLUDE_DIR " ]]; then
112+ gosec_cmd+=" -exclude-dir=$GOSEC_EXCLUDE_DIR "
113+ fi
114+ if [[ -n " $GOSEC_RULES " ]]; then
115+ gosec_cmd+=" -severity=$GOSEC_RULES "
116+ fi
117+ eval $gosec_cmd || :
118+ fi
119+
120+ # ESLint rules setup (needed for JS/TS SAST)
121+ ESLINT_EXCLUDE_DIR=${INPUT_ESLINT_EXCLUDE_DIR:- }
122+ ESLINT_RULES=${INPUT_ESLINT_RULES:- }
123+ if [[ -z " $ESLINT_RULES " ]]; then
124+ ESLINT_RULES=$( cat << 'EOF '
26125security/detect-eval-with-expression,
27126security/detect-non-literal-require,
28127security/detect-non-literal-fs-filename,
@@ -75,14 +174,14 @@ security/detect-object-injection,
75174@typescript-eslint/prefer-as-const
76175EOF
77176)
78- fi
177+ fi
79178
80- # Convert rule list to JSON map: "rule-name": "error"
81- ESLINT_RULES_JSON=$( echo " $ESLINT_RULES " | tr ' ,' ' \n' | sed ' /^\s*$/d' | awk ' {printf "\"%s\": \"error\",\n", $0}' | sed ' $s/,$//' )
179+ # Convert rule list to JSON map: "rule-name": "error"
180+ ESLINT_RULES_JSON=$( echo " $ESLINT_RULES " | tr ' ,' ' \n' | sed ' /^\s*$/d' | awk ' {printf "\"%s\": \"error\",\n", $0}' | sed ' $s/,$//' )
82181
83- if [[ ! -f " $WORKSPACE /eslint.config.mjs" ]]; then
84- echo " Adding fallback ESLint config"
85- cat << EOF > "$WORKSPACE /eslint.config.mjs"
182+ if [[ ! -f " $WORKSPACE /eslint.config.mjs" ]]; then
183+ echo " Adding fallback ESLint config"
184+ cat << EOF > "$WORKSPACE /eslint.config.mjs"
86185export default [
87186 {
88187 files: ['**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx'],
@@ -92,94 +191,38 @@ $ESLINT_RULES_JSON
92191 },
93192];
94193EOF
95- fi
96-
97- eslint_cmd=" npx --yes eslint --config $WORKSPACE /eslint.config.mjs $WORKSPACE --ext .js,.jsx,.ts,.tsx --format json --output-file $OUTPUT_DIR /eslint_output.json"
194+ fi
98195
196+ # Run ESLint on JS/TS files
197+ if [[ " ${# js_files[@]} " -gt 0 && " ${INPUT_JAVASCRIPT_SAST_ENABLED:- false} " == " true" ]]; then
198+ echo " Running ESLint on JS/TS files: ${js_files[*]} "
199+ eslint_cmd=" npx --yes eslint --config $WORKSPACE /eslint.config.mjs ${js_files[*]} --ext .js,.jsx,.ts,.tsx --format json --output-file $TEMP_OUTPUT_DIR /eslint_output.json"
99200 if [[ -n " $ESLINT_EXCLUDE_DIR " ]]; then
100201 IFS=' ,' read -ra EXCLUDES <<< " $ESLINT_EXCLUDE_DIR"
101202 for exclude in " ${EXCLUDES[@]} " ; do
102203 eslint_cmd+=" --ignore-pattern $exclude "
103204 done
104205 fi
105-
106206 eval $eslint_cmd || :
107207fi
108208
109-
110- # Run Bandit (Python SAST) if enabled
111- if [[ " $INPUT_PYTHON_SAST_ENABLED " == " true" ]]; then
112- echo " Running Bandit"
113- bandit_cmd=" bandit -r $GITHUB_WORKSPACE -f json -o /tmp/bandit_output.json"
114- if [[ -n " $BANDIT_EXCLUDE_DIR " ]]; then
115- bandit_cmd+=" --exclude $BANDIT_EXCLUDE_DIR "
116- fi
117- if [[ -n " $BANDIT_RULES " ]]; then
118- bandit_cmd+=" --skip $BANDIT_RULES "
119- fi
120- echo $bandit_cmd
121- eval $bandit_cmd || :
122- fi
123-
124- # Run Gosec (Golang SAST) if enabled
125- if [[ " $INPUT_GOLANG_SAST_ENABLED " == " true" ]]; then
126- echo " Running Gosec"
127- gosec_cmd=" gosec -fmt json -out /tmp/gosec_output.json "
128- if [[ -n " $GOSEC_EXCLUDE_DIR " ]]; then
129- gosec_cmd+=" -exclude-dir=$GOSEC_EXCLUDE_DIR "
130- fi
131- if [[ -n " $GOSEC_RULES " ]]; then
132- gosec_cmd+=" -severity=$GOSEC_RULES "
133- fi
134- gosec_cmd+=" $GITHUB_WORKSPACE /..."
135- eval $gosec_cmd || :
136- fi
137-
138- # Run Trivy on Container Images if enabled
139- if [[ " $INPUT_TRIVY_IMAGE_ENABLED " == " true" ]]; then
140- echo " Running Trivy on Container Images"
141- IFS=' ,' read -ra DOCKER_IMAGES <<< " ${INPUT_DOCKER_IMAGES}"
142- for image in " ${DOCKER_IMAGES[@]} " ; do
143- echo " Scanning image: $image "
144- trivy image --scanners vuln --format json --output " /tmp/trivy_image_${image// \/ / _} .json" " $image " || :
145- done
146- fi
147-
148- # Run Trivy on Dockerfiles if enabled
149- if [[ " $INPUT_TRIVY_DOCKERFILE_ENABLED " == " true" ]]; then
150- IFS=' ,' read -ra DOCKERFILES <<< " ${INPUT_DOCKERFILES}"
151- for dockerfile in " ${DOCKERFILES[@]} " ; do
152- echo " Scanning Dockerfile: $dockerfile "
153- trivy config --format json --output " /tmp/trivy_dockerfile_${dockerfile// \/ / _} .json" " $GITHUB_WORKSPACE /$dockerfile " || :
154- done
209+ # Move output files (no-op if already in correct place)
210+ # Only cd in GitHub Actions, not local
211+ if [ " $LOCAL_TESTING " != " true" ]; then
212+ cd " $WORKSPACE "
155213fi
156-
157- # Run Secret Scanning (Trufflehog) if enabled
158- if [[ " $INPUT_SECRET_SCANNING_ENABLED " == " true" ]]; then
159- echo " Running Secret Scanning with Trufflehog"
160- trufflehog_cmd=" trufflehog filesystem "
161- TRUFFLEHOG_EXCLUDE_FILE=$( mktemp)
162- if [[ -n " $TRUFFLEHOG_EXCLUDE_DIR " ]]; then
163- IFS=' ,' read -ra EXCLUDE_DIRS <<< " $TRUFFLEHOG_EXCLUDE_DIR"
164- for dir in " ${EXCLUDE_DIRS[@]} " ; do
165- echo " $dir " >> " $TRUFFLEHOG_EXCLUDE_FILE "
166- done
167- trufflehog_cmd+=" -x $TRUFFLEHOG_EXCLUDE_FILE "
168- fi
169- if [[ -n " $TRUFFLEHOG_RULES " ]]; then
170- trufflehog_cmd+=" --rules $TRUFFLEHOG_RULES "
171- fi
172- trufflehog_cmd+=" --no-verification -j $GITHUB_WORKSPACE > /tmp/trufflehog_output.json"
173- eval $trufflehog_cmd || :
214+ # Run the Python script from the correct directory and path
215+ if [[ -n " $PY_SCRIPT_PATH " ]]; then
216+ FINAL_PY_SCRIPT_PATH=" $PY_SCRIPT_PATH "
217+ elif [[ " $DEV_MODE " == " true" ]]; then
218+ FINAL_PY_SCRIPT_PATH=" $WORKSPACE /src/socket_external_tools_runner.py"
219+ else
220+ FINAL_PY_SCRIPT_PATH=" $WORKSPACE /socket_external_tools_runner.py"
174221fi
175222
176- # Execute the custom Python script to process findings
177- if [ " $LOCAL_TESTING " != " true" ]; then
178- cd /
179- fi
180- mv /tmp/* .json .
181- if [ " $LOCAL_TESTING " != " true" ]; then
182- python socket_external_tools_runner.py
223+ if [[ -f " $FINAL_PY_SCRIPT_PATH " ]]; then
224+ python " $FINAL_PY_SCRIPT_PATH "
183225else
184- python socket_external_tools_runner.py
226+ echo " Error: Python script not found at $FINAL_PY_SCRIPT_PATH " >&2
227+ exit 1
185228fi
0 commit comments