11name : OWASP PR Scanner
22
33on :
4- pull_request :
5- paths :
6- - ' src/**'
7- - ' backend/**'
8- - ' app/**'
9- - ' services/**'
10- - ' .github/workflows/**'
11- - ' scanner/**'
4+ pull_request_target :
5+ types : [opened, synchronize, reopened]
6+
7+ permissions :
8+ contents : read
9+ pull-requests : write
1210
1311jobs :
1412 scan :
1513 runs-on : ubuntu-latest
14+
1615 steps :
17- - name : Checkout
16+ - name : Checkout PR HEAD
1817 uses : actions/checkout@v4
1918 with :
19+ ref : ${{ github.event.pull_request.head.sha }}
2020 fetch-depth : 0
2121
2222 - name : Set up Python
@@ -39,44 +39,111 @@ jobs:
3939 run : |
4040 BASE_SHA="${{ github.event.pull_request.base.sha }}"
4141 HEAD_SHA="${{ github.event.pull_request.head.sha }}"
42-
43- RAW=$(git diff --name-only "$BASE_SHA" "$HEAD_SHA" || true)
44-
45- APP_CHANGED=$(echo "$RAW" \
42+ RAW="$(git diff --name-only "$BASE_SHA" "$HEAD_SHA" || true)"
43+ APP_CHANGED="$(echo "$RAW" \
4644 | grep -E '\.(js|jsx|ts|tsx|py|java|go|rb|php|html|css|md)$' \
47- | grep -E '^(src/|backend/|app/|services/)' || true)
48-
49- SCANNER_ONLY=$(echo "$RAW" | grep -E '^scanner/' || true)
50-
45+ | grep -E '^(src/|backend/|app/|services/)' || true)"
46+ SCANNER_ONLY="$(echo "$RAW" | grep -E '^scanner/' || true)"
5147 if [ -z "$APP_CHANGED" ] && [ -n "$SCANNER_ONLY" ]; then
5248 echo "only_scanner_changes=true" >> $GITHUB_OUTPUT
53- exit 0
49+ else
50+ if [ -z "$APP_CHANGED" ]; then
51+ APP_CHANGED="$(git ls-files src backend app services 2>/dev/null || true)"
52+ fi
53+ echo "changed_files<<EOF" >> $GITHUB_OUTPUT
54+ echo "$APP_CHANGED" >> $GITHUB_OUTPUT
55+ echo "EOF" >> $GITHUB_OUTPUT
5456 fi
5557
56- if [ -z "$APP_CHANGED" ]; then
57- APP_CHANGED="$(git ls-files src backend app services 2>/dev/null || true)"
58- fi
59-
60- echo "CHANGED_FILES<<EOF" >> "$GITHUB_ENV"
61- echo "$APP_CHANGED" >> "$GITHUB_ENV"
62- echo "EOF" >> "$GITHUB_ENV"
63-
6458 - name : Skip when only scanner/** changed
6559 if : steps.diff.outputs.only_scanner_changes == 'true'
6660 run : echo "Only scanner/** changed; skipping scan."
6761
6862 - name : Run OWASP scanner on changed files
6963 if : steps.diff.outputs.only_scanner_changes != 'true'
64+ id : owasp
7065 shell : bash
7166 run : |
72- if [ -z "${CHANGED_FILES}" ]; then
73- echo "Nothing to scan."
67+ CHANGED_FILES="${{ steps.diff.outputs.changed_files }}"
68+ if [ -z "$CHANGED_FILES" ]; then
69+ echo "Nothing to scan." | tee owasp-results.txt
70+ echo "vulnerabilities_found=false" >> $GITHUB_OUTPUT
7471 exit 0
7572 fi
73+
74+ : > owasp-results.txt
7675 EXIT=0
7776 while IFS= read -r file; do
7877 [ -z "$file" ] && continue
79- echo "Scanning: $file"
80- python -m scanner.main "$file" || EXIT=1
81- done <<< "${CHANGED_FILES}"
82- exit $EXIT
78+ echo "### File: $file" >> owasp-results.txt
79+ echo '```' >> owasp-results.txt
80+ python -m scanner.main "$file" >> owasp-results.txt 2>&1 || EXIT=1
81+ echo '```' >> owasp-results.txt
82+ echo "" >> owasp-results.txt
83+ done <<< "$CHANGED_FILES"
84+
85+ if [ $EXIT -ne 0 ]; then
86+ echo "vulnerabilities_found=true" >> $GITHUB_OUTPUT
87+ else
88+ echo "vulnerabilities_found=false" >> $GITHUB_OUTPUT
89+ fi
90+
91+ exit $EXIT || true
92+
93+ - name : Create PR comment body
94+ id : comment
95+ if : always() && steps.diff.outputs.only_scanner_changes != 'true'
96+ shell : bash
97+ run : |
98+ if [ -f owasp-results.txt ]; then
99+ RESULTS="$(cat owasp-results.txt)"
100+ else
101+ RESULTS="No scanner output available."
102+ fi
103+
104+ if [ "${{ steps.owasp.outputs.vulnerabilities_found }}" == "true" ]; then
105+ echo 'comment_body<<EOF' >> $GITHUB_ENV
106+ echo '## 🔒 OWASP Scanner Results' >> $GITHUB_ENV
107+ echo '' >> $GITHUB_ENV
108+ echo 'Vulnerabilities were detected in the changed files:' >> $GITHUB_ENV
109+ echo '' >> $GITHUB_ENV
110+ echo '```' >> $GITHUB_ENV
111+ echo "$RESULTS" >> $GITHUB_ENV
112+ echo '```' >> $GITHUB_ENV
113+ echo '' >> $GITHUB_ENV
114+ echo '⛔ Please address these findings before merging.' >> $GITHUB_ENV
115+ echo 'EOF' >> $GITHUB_ENV
116+ else
117+ echo 'comment_body<<EOF' >> $GITHUB_ENV
118+ echo '## 🔒 OWASP Scanner Results' >> $GITHUB_ENV
119+ echo '' >> $GITHUB_ENV
120+ echo 'No vulnerabilities detected in the changed files.' >> $GITHUB_ENV
121+ echo '' >> $GITHUB_ENV
122+ echo '```' >> $GITHUB_ENV
123+ echo "$RESULTS" >> $GITHUB_ENV
124+ echo '```' >> $GITHUB_ENV
125+ echo '✅ Good to go.' >> $GITHUB_ENV
126+ echo 'EOF' >> $GITHUB_ENV
127+ fi
128+
129+ - name : Comment PR
130+ uses : peter-evans/create-or-update-comment@v4
131+ if : always() && steps.diff.outputs.only_scanner_changes != 'true'
132+ with :
133+ issue-number : ${{ github.event.pull_request.number }}
134+ body : ${{ env.comment_body }}
135+
136+ - name : Upload scan artifact
137+ if : always()
138+ uses : actions/upload-artifact@v4
139+ with :
140+ name : owasp-scan-results
141+ path : |
142+ owasp-results.txt
143+ retention-days : 5
144+
145+ - name : Fail if vulnerabilities found
146+ if : steps.owasp.outputs.vulnerabilities_found == 'true'
147+ run : |
148+ echo "::error::OWASP scanner reported vulnerabilities. Failing the job."
149+ exit 1
0 commit comments