diff --git a/.gitea/workflows/security-scan.yml b/.gitea/workflows/security-scan.yml index e2dd42f..8ef599b 100644 --- a/.gitea/workflows/security-scan.yml +++ b/.gitea/workflows/security-scan.yml @@ -17,6 +17,11 @@ on: required: false type: string default: 'auto' + semgrep-exclude-rules: + description: 'Semgrep rule IDs to exclude, comma-separated (e.g. csharp.lang.security.sqli.csharp-sqli)' + required: false + type: string + default: '' jobs: semgrep: @@ -36,9 +41,21 @@ jobs: - name: Run Semgrep scan # --config=auto pulls language-appropriate rule packs from semgrep.dev - # without requiring an account. --error makes the job fail when - # findings at or above the chosen severity exist. - run: semgrep scan --config=${{ inputs.semgrep-config }} --error --severity=ERROR --severity=WARNING + # without requiring an account. --error makes the job fail when ERROR + # findings exist. WARNING-level rules still run for visibility but do + # not fail the build (they would dominate the noise). + # Per-repo rule exclusion via the semgrep-exclude-rules input. + env: + EXCLUDE_RULES: ${{ inputs.semgrep-exclude-rules }} + run: | + args="--config=${{ inputs.semgrep-config }} --error --severity=ERROR" + if [ -n "$EXCLUDE_RULES" ]; then + for rule in $(echo "$EXCLUDE_RULES" | tr ',' ' '); do + args="$args --exclude-rule=$rule" + done + fi + echo "Running: semgrep scan $args" + semgrep scan $args trivy: name: Trivy Vulnerability Scan diff --git a/README.md b/README.md index f3315a8..4e3fbd5 100644 --- a/README.md +++ b/README.md @@ -34,18 +34,25 @@ Both jobs run in parallel. Either failing fails the calling workflow. ## Tuning per consumer -The reusable workflow accepts two optional inputs: +The reusable workflow accepts three optional inputs: ```yaml jobs: scan: uses: JonKazama-Hellion/security-workflows/.gitea/workflows/security-scan.yml@main with: - severity: 'CRITICAL' # default 'CRITICAL,HIGH' + severity: 'CRITICAL' # default 'CRITICAL,HIGH' semgrep-config: 'p/owasp-top-ten' # default 'auto' + semgrep-exclude-rules: 'csharp.lang.security.sqli.csharp-sqli,javascript.express.security.audit.express-cookie' ``` -`severity` is the Trivy threshold, `semgrep-config` swaps the rule pack (e.g. `p/owasp-top-ten`, `p/javascript`, `p/csharp`). +| Input | Default | What | +|---|---|---| +| `severity` | `CRITICAL,HIGH` | Trivy severity threshold for failing the build | +| `semgrep-config` | `auto` | Semgrep rule pack (e.g. `p/owasp-top-ten`, `p/javascript`, `p/csharp`) | +| `semgrep-exclude-rules` | `` (empty) | Comma-separated Semgrep rule IDs to skip in this repo. Useful for context-specific false positives, e.g. SQL-injection rules in a local-only plugin where the SQL strings come from code constants and the values are bound via SqlParameter. | + +Note that Semgrep is configured to fail the build only on `ERROR`-severity findings. `WARNING`-level rules still run for visibility but do not block, which keeps the noise floor low. ## Pinning