-
-
Notifications
You must be signed in to change notification settings - Fork 10
152 lines (136 loc) · 5.34 KB
/
security-sast-go.yml
File metadata and controls
152 lines (136 loc) · 5.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
name: Go SAST (gosec)
on:
workflow_call:
inputs:
exclude_dirs:
description: 'Comma-separated directories to exclude'
type: string
default: 'testdata'
exclude_rules:
description: 'Comma-separated gosec rules to exclude (e.g., G304,G301)'
type: string
default: ''
outputs:
findings:
description: 'Total gosec findings'
value: ${{ jobs.gosec.outputs.findings }}
high:
description: 'HIGH severity findings'
value: ${{ jobs.gosec.outputs.high }}
medium:
description: 'MEDIUM severity findings'
value: ${{ jobs.gosec.outputs.medium }}
low:
description: 'LOW severity findings'
value: ${{ jobs.gosec.outputs.low }}
suppressed:
description: 'Suppressed findings (#nosec)'
value: ${{ jobs.gosec.outputs.suppressed }}
jobs:
gosec:
name: Gosec Security Scan
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: read
security-events: write
outputs:
findings: ${{ steps.scan.outputs.findings }}
high: ${{ steps.scan.outputs.high }}
medium: ${{ steps.scan.outputs.medium }}
low: ${{ steps.scan.outputs.low }}
suppressed: ${{ steps.scan.outputs.suppressed }}
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Set up Go
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6
with:
go-version-file: 'go.mod'
cache: true
- name: Install Gosec
run: go install github.com/securego/gosec/v2/cmd/gosec@latest
- name: Run Gosec
id: scan
env:
EXCLUDE_DIRS_INPUT: ${{ inputs.exclude_dirs }}
EXCLUDE_RULES_INPUT: ${{ inputs.exclude_rules }}
run: |
echo "::group::Gosec Security Scan"
# Build exclude-dir arguments
EXCLUDE_ARGS=""
IFS=',' read -ra DIRS <<< "$EXCLUDE_DIRS_INPUT"
for dir in "${DIRS[@]}"; do
dir=$(echo "$dir" | xargs) # trim whitespace
if [ -n "$dir" ]; then
EXCLUDE_ARGS="$EXCLUDE_ARGS -exclude-dir=$dir"
fi
done
# Build exclude rules argument
EXCLUDE_RULES=""
if [ -n "$EXCLUDE_RULES_INPUT" ]; then
EXCLUDE_RULES="-exclude=$EXCLUDE_RULES_INPUT"
fi
# Run gosec with JSON output
gosec -fmt json -out gosec.json -stdout -verbose=text \
$EXCLUDE_ARGS $EXCLUDE_RULES \
./... || true
# Run gosec with SARIF output (suppressed findings excluded)
gosec -fmt sarif -out gosec.sarif \
$EXCLUDE_ARGS $EXCLUDE_RULES \
./... || true
# Parse results
if [ -f gosec.json ]; then
FINDINGS=$(jq '.Issues | length' gosec.json 2>/dev/null || echo "0")
HIGH=$(jq '[.Issues[]? | select(.severity == "HIGH")] | length' gosec.json 2>/dev/null || echo "0")
MEDIUM=$(jq '[.Issues[]? | select(.severity == "MEDIUM")] | length' gosec.json 2>/dev/null || echo "0")
LOW=$(jq '[.Issues[]? | select(.severity == "LOW")] | length' gosec.json 2>/dev/null || echo "0")
SUPPRESSED=$(jq '[.Issues[]? | select(.nosec == true)] | length' gosec.json 2>/dev/null || echo "0")
echo "findings=$FINDINGS" >> $GITHUB_OUTPUT
echo "high=$HIGH" >> $GITHUB_OUTPUT
echo "medium=$MEDIUM" >> $GITHUB_OUTPUT
echo "low=$LOW" >> $GITHUB_OUTPUT
echo "suppressed=$SUPPRESSED" >> $GITHUB_OUTPUT
# Warnings for severity levels
if [ "$HIGH" -gt 0 ]; then
echo "::error::$HIGH HIGH severity gosec finding(s)"
fi
if [ "$MEDIUM" -gt 0 ]; then
echo "::warning::$MEDIUM MEDIUM severity gosec finding(s)"
fi
if [ "$SUPPRESSED" -gt 0 ]; then
echo "::notice::$SUPPRESSED finding(s) suppressed via #nosec"
fi
else
echo "findings=0" >> $GITHUB_OUTPUT
echo "high=0" >> $GITHUB_OUTPUT
echo "medium=0" >> $GITHUB_OUTPUT
echo "low=0" >> $GITHUB_OUTPUT
echo "suppressed=0" >> $GITHUB_OUTPUT
fi
echo "::endgroup::"
# Write summary
echo "### Gosec Results" >> $GITHUB_STEP_SUMMARY
echo "| Severity | Count |" >> $GITHUB_STEP_SUMMARY
echo "|----------|-------|" >> $GITHUB_STEP_SUMMARY
echo "| HIGH | $HIGH |" >> $GITHUB_STEP_SUMMARY
echo "| MEDIUM | $MEDIUM |" >> $GITHUB_STEP_SUMMARY
echo "| LOW | $LOW |" >> $GITHUB_STEP_SUMMARY
echo "| Suppressed | $SUPPRESSED |" >> $GITHUB_STEP_SUMMARY
echo "| **Total** | **$FINDINGS** |" >> $GITHUB_STEP_SUMMARY
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@c10b8064de6f491fea524254123dbe5e09572f13 # v4
with:
sarif_file: gosec.sarif
category: gosec
continue-on-error: true
- name: Upload artifacts
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
if: always()
with:
name: gosec-results
path: |
gosec.json
gosec.sarif
retention-days: 30
if-no-files-found: ignore