Die Oberfläche ist lokalisiert; Skill-Beschreibungen und -Dokumente werden per KI automatisch in Ihre Sprache übersetzt. Code, Befehle, Pfade und Fachbegriffe bleiben im Original, maßgeblich ist das Dokument des Autors.
Skills entdecken
Daten und Forschung · SKILL.md

sast-tooling

sast-tooling

Use when running Static Application Security Testing (SAST) on a codebase — wraps bandit (Python), semgrep (multi-language, OSS rule packs), eslint-security (JavaScript/TypeScript), and CodeQL (GitHub-hosted, license-gated for private repos). Standardises on SARIF 2.1.0 output, feeds the G_SECURE gate in _meta/gates.py, integrates with forge Step 1 advisory…

Independent GitHub snapshot · Automated classification · Original documentation governs

Skill-Dokumentation

GitHub

name: sast-tooling description: Use when running Static Application Security Testing (SAST) on a codebase — wraps bandit (Python), semgrep (multi-language, OSS rule packs), eslint-security (JavaScript/TypeScript), and CodeQL (GitHub-hosted, license-gated for private repos). Standardises on SARIF 2.1.0 output, feeds the G_SECURE gate in _meta/gates.py, integrates with forge Step 1 advisory, alf sweeps, and pre-commit/CI workflows. Trigger on - SAST, static analysis, bandit, semgrep, CodeQL, eslint-security, SARIF, security linting, code-injection scan, "scan code for vulnerabilities", "find security bugs", "OWASP scan".

SAST Tooling

Overview

Static Application Security Testing (SAST) — find security defects in source code without running it. SAST catches the LOW-MEDIUM hygiene defects (verify=False, eval(user_input), hardcoded password= strings, unsafe deserialisation, weak cryptography) that secret-scanning and dep-currency-check don't cover. Per the S038 alf sweep verdict, this skill closes the "no SAST runner" gap (finding F-H2).

The runner choices in 2026, with Gemini freshness-probe corroboration (2026-05-22):

ToolLanguagesMaintenanceSpeedFalse positivesUse case
banditPython onlyActive (v1.9.4 Feb 2026, py3.10+ required)FastLow-mediumPython-specific; CI gate; pre-commit
semgrepMulti-language (Python/JS/TS/Java/Go/Ruby/PHP/C/+more)Active (v1.x, no breaking v2.0 — Agentic IDE hooks added 2025-26)FastMedium (configurable per ruleset)The de-facto multi-language SAST; default choice for polyglot repos
eslint-securityJavaScript / TypeScriptActive (eslint-plugin-security)FastMediumJS/TS-specific; runs as ESLint plugin; CI gate
CodeQLMany (C/C++/C#/Go/Java/JS/Python/Ruby/Swift)Active (GitHub)Slower (compile-then-analyze)Low (deep dataflow)Best for high-stakes / open-source; license-gated for private repos since Apr 2025

Companion skills:

  • python-auth-security — what the findings SHOULD look like (no eval, parameterised SQL, etc.)
  • secret-scanning — sister skill for secrets (gitleaks/trufflehog)
  • dep-currency-check — sister skill for dependency CVEs (orthogonal to source-level SAST)
  • llm-security — sister skill for LLM-specific defects
  • _meta/gates.py (G_SECURE) — the gate this skill feeds

1. Tool selection — when to use which

ScenarioTool
Pure-Python projectbandit (cheap, Python-specific) + optional semgrep --config p/python for broader coverage
JS/TS projecteslint-security in eslint config + optional semgrep --config p/javascript
Polyglot repo (Python + JS + Go + ...)semgrep with bundled or custom rulesets — single runner, single SARIF output
Public repo on GitHubCodeQL via Actions (free for public repos) + semgrep for fast iteration
Private repo on GitHub with GHAS Code SecurityCodeQL + semgrep
Private repo without GHAS budgetsemgrep + tool-specific (bandit / eslint-security) — CodeQL is $30/committer/month standalone since Apr 2025
Air-gapped / offline environmentbandit + semgrep (both offline-capable with bundled rulesets)
Quick-iteration developer-loop scansemgrep autofix (--autofix) for the small set of safe-auto-fix rules
Highest-confidence deep dataflow analysisCodeQL

The default 2026 setup for a polyglot CI gate: semgrep + bandit (Python) + eslint-security (JS/TS), each emitting SARIF, aggregated by G_SECURE. CodeQL adds the dataflow tier when budget / license permits.


2. Install Commands

RHEL 9 / AlmaLinux 9 / Rocky 9

# bandit
pip install --user bandit
bandit --version  # expects 1.9.x

# semgrep
pip install --user semgrep
semgrep --version  # expects 1.16x.x

# eslint-security (Node.js project)
npm install --save-dev eslint eslint-plugin-security

# CodeQL CLI (standalone — for use outside GHAS)
# Download from: https://github.com/github/codeql-cli-binaries/releases
# Place under ~/.local/bin/codeql

Debian 12 / Ubuntu 24.04

# Same pip / npm commands as RHEL
pip install --user bandit semgrep
# eslint-security per project

Windows 11

# Via pip (Python tools)
py -m pip install --user bandit semgrep
# Or scoop/chocolatey:
scoop install semgrep

Verify via env-adoption (S038 Batch A added these to the inventory):

jq '.tools | {bandit, semgrep, "pip-audit", "osv-scanner"}' ~/.claude/state/inventory.json

3. SARIF as the canonical output

SARIF 2.1.0 is the multi-tool standard. Every wrapper this skill describes emits SARIF, and G_SECURE consumes SARIF. This means findings from bandit / semgrep / eslint-security / CodeQL aggregate uniformly into one report, ingestable by GitHub Advanced Security, VS Code, JetBrains, Sonarqube, and most enterprise dashboards.

# bandit → SARIF
bandit -r src/ -f sarif -o /tmp/bandit.sarif

# semgrep → SARIF
semgrep --config auto --sarif --output /tmp/semgrep.sarif

# eslint-security → SARIF
npx eslint --format @microsoft/eslint-formatter-sarif --output-file /tmp/eslint.sarif src/

# CodeQL → SARIF (via Action; CLI: codeql database analyze --format=sarif-latest)

G_SECURE aggregates by reading SARIF and applying the configured severity threshold.


4. Canonical CI integration

4.1 GitHub Actions (.github/workflows/sast.yml)

name: sast
on: [pull_request, push]
jobs:
  semgrep:
    runs-on: ubuntu-latest
    permissions: { security-events: write }
    steps:
      - uses: actions/checkout@v4
      - uses: returntocorp/semgrep-action@v1
        with:
          config: >-
            p/python p/javascript p/typescript p/security-audit p/secrets
            p/r2c-security-audit p/owasp-top-ten
          generateSarif: true
      - uses: github/codeql-action/upload-sarif@v3
        with: { sarif_file: semgrep.sarif }

  bandit:
    runs-on: ubuntu-latest
    if: contains(github.event.repository.topics, 'python') # gate on python repos
    permissions: { security-events: write }
    steps:
      - uses: actions/checkout@v4
      - run: pip install bandit
      - run: bandit -r . -ll -f sarif -o bandit.sarif || true
      - uses: github/codeql-action/upload-sarif@v3
        with: { sarif_file: bandit.sarif }

  codeql:
    # Optional — CodeQL for deeper dataflow
    runs-on: ubuntu-latest
    permissions: { security-events: write }
    strategy:
      matrix: { language: [python, javascript] }
    steps:
      - uses: actions/checkout@v4
      - uses: github/codeql-action/init@v3
        with: { languages: ${{ matrix.language }} }
      - uses: github/codeql-action/analyze@v3

4.2 Pre-commit hook (POSIX)

# .git/hooks/pre-commit (extract)
if command -v semgrep >/dev/null 2>&1; then
  semgrep --config auto --error --quiet --skip-unknown-extensions $(git diff --cached --name-only) \
    || { echo "[semgrep] BLOCKING — review findings"; exit 1; }
fi

4.3 The G_SECURE gate (S038 Batch E)

python3 ~/.claude/skills/_meta/gates.py G_SECURE /path/to/project \
  --sast-mode advisory                # never blocks; reports
python3 ~/.claude/skills/_meta/gates.py G_SECURE /path/to/project \
  --sast-mode strict \
  --severity high                     # blocks on high+critical
python3 ~/.claude/skills/_meta/gates.py G_SECURE /path/to/project \
  --sast-mode strict \
  --severity critical \
  --runner semgrep                    # explicit runner choice

Exit codes mirror the family:

  • 0 = pass (no findings at/above severity, OR advisory mode)
  • 2 = fail (strict mode AND findings at/above severity)
  • 3 = environmental error (no SAST runner available)

5. Per-runner notes

5.1 bandit (Python)

  • Confidence levels: HIGH / MEDIUM / LOW. Default rules-loaded at all levels. -ll = medium-or-higher severity + medium-or-higher confidence. Recommended CI baseline.
  • -ll filter is the most-cited 2026 baseline by the OpenSSF Python WG (the LOW-confidence rules produce too many FPs).
  • Common-rule cheat-sheet:
    • B101 — assert outside tests (False in production)
    • B105/106/107 — hardcoded password strings/funcargs/defaults
    • B301 — pickle deserialisation (HIGH severity)
    • B324 — weak hash (md5/sha1)
    • B501 — verify=False in requests
    • B602/603/605/607 — subprocess shell-injection variants
    • B608 — SQL string concat
    • B701 — Jinja2 autoescape disabled
  • Inline suppress: # nosec: <rule-id> — justification
  • Project config: bandit.yaml or pyproject.toml [tool.bandit]

5.2 semgrep (multi-language)

  • Free-tier rulesets: p/security-audit, p/owasp-top-ten, p/secrets, language-specific p/python / p/javascript / etc. The 2026 build has Agentic IDE hooks (Claude Code / Windsurf integration).
  • Autofix: semgrep --autofix for the small subset of rules marked fix: in the YAML. Safe-by-default — only applies fixes that don't change semantics.
  • Custom rules: YAML under .semgrep/. Pattern-based matching with metavariables; far more flexible than bandit.
  • Inline suppress: // nosemgrep: <rule-id> (or language-comment variant)
  • Project config: .semgrep.yml or --config <path>

5.3 eslint-security (JS/TS)

  • eslint-plugin-security provides a focused security-only ruleset; add to your eslint config:
    {"extends": ["plugin:security/recommended"], "plugins": ["security"]}
    
  • Coverage is narrower than semgrep for JS — they're complementary, not redundant.
  • Key rules: detect-eval-with-expression, detect-non-literal-fs-filename, detect-non-literal-regexp, detect-unsafe-regex, detect-object-injection.

5.4 CodeQL

  • GHAS Code Security add-on standalone: $30/committer/month (since Apr 2025 — Gemini freshness probe).
  • Open-source / public repos: free via GitHub Actions.
  • Strengths: deep dataflow analysis catches taint flows that pattern-matchers miss.
  • Slow (compile-then-analyse) — use for nightly / pre-release scans, not every PR.
  • Output: SARIF, ingestable by GHAS or third parties.

6. Security Hardening (the rules for THIS skill's usage)

  1. Layer SAST + secrets + deps + LLM-security — each tool catches different things; none is sufficient alone.
  2. Run advisory first, baseline existing findings, then go strict.
  3. Document every suppression — # nosec: B608 — reason not bare # nosec.
  4. CI gates use SARIF — feed into GitHub Advanced Security / Sonarqube / enterprise dashboards.
  5. CI runs at least one SAST runner (semgrep is the cheapest baseline).
  6. Pin SAST runner versions — semgrep's rule packs change, bandit's rule list updates; record the version in CI logs (bandit --version / semgrep --version).
  7. Keep SAST runner versions current via dep-currency-check — semgrep ships new rule packs continuously.
  8. Don't --autofix blindly in CI — review the diff. Auto-fixed code can change semantics for edge cases the fix-rule didn't anticipate.
  9. Custom rules are project-specific — file under .semgrep/ in the repo, code-review additions.
  10. alf sweep includes SAST runner currency — sees bandit/semgrep/gitleaks versions in the inventory and flags if the project's pinned version drifts.

7. Anti-patterns

Anti-patternWhy it failsCorrect approach
Run bandit with default confidence (LOW) in CI gate from day oneFP storm; team learns to --no-verifyUse bandit -ll; tune over time
One tool onlyEach catches different thingsLayer at least 2 of {semgrep, bandit, eslint-security}
# nosec without justificationPermanent exception with no traceable reasonRequired format: # nosec: <id> — reason
Auto-fix in CI without reviewRule-based fixes can break edge-case semantics--autofix only locally, then code-review the diff
Skip SAST because dep-currency-check + secret-scanning are runningSister skills cover different threats; SAST adds source-level findingsRun all three (G_SECRETS_SCAN + G_DEP_CURRENCY + G_SECURE)
Treat SAST FPs as bugs in the SAST toolTriaging FPs is the work; modern SAST is by-design over-reportingTriage, suppress with reason, OR tune the ruleset
Run CodeQL on every PRSlow; eats GHAS minutes; better for nightlysemgrep / bandit on PR, CodeQL nightly
Custom rules in a single project's .semgrep/ without sharing backReinvents the wheel across projectsMaintain shared org-level rule packs

8. Selection Cheatsheet

  • Polyglot CI gate, fast → semgrep --config auto with --severity ERROR --error
  • Python project + needs deep dataflow → bandit + CodeQL (Python)
  • JS/TS in mixed repo → semgrep p/javascript + eslint-security inside ESLint
  • Just want quick "is this code obviously bad" check locally → semgrep --config p/security-audit --autofix (local only)
  • Need SARIF aggregated to GitHub Advanced Security → upload via github/codeql-action/upload-sarif@v3
  • Need G_SECURE for bob WP-completion gate → python3 ~/.claude/skills/_meta/gates.py G_SECURE --sast-mode strict
  • Need an advisory pass for forge Step 1 → --sast-mode advisory

9. Gotchas

GotchaDetail
semgrep --config auto requires metrics: on (default) to authenticateFor air-gapped, use --config p/<ruleset> with explicit packs
bandit can't analyse code that doesn't parseIf your code uses syntax newer than the bandit-supporting Python (1.9.4 → py 3.14), bandit will fail; pin a compatible Python
eslint-plugin-security needs eslint flat-config in modern repos.eslintrc.json legacy format still works, but new repos default to eslint.config.js
CodeQL pricing changed Apr 2025Public repos free; private repos require GHAS Code Security add-on at $30/committer/month
SARIF schema versions can clashAll four runners standardise on 2.1.0 as of 2026; older outputs may need conversion
semgrep autofix on == → === (JS) is safe-mostly but rarely "what the developer wanted"Review every autofix
Custom rule false-positives in semgrep need careful pattern designUse pattern-not and metavariable-regex to scope tightly
bandit B105 flags password = "changeme" even in test fixturesSuppress with # nosec: B105 — test fixture, not a real credential

10. Update triggers (alf scans these)

  • bandit major version bump (currently 1.9.x as of 2026-05)
  • semgrep major version bump (still on 1.x, but 2.0 would be material)
  • semgrep rule pack additions for new attack patterns
  • ESLint flat-config completion (deprecation of .eslintrc.* formats)
  • New OWASP Top 10 edition (rules need re-mapping)
  • CodeQL pricing / availability change
  • New SARIF version (currently 2.1.0)
  • Annual review on 2027-05-24

11. See Also

NeedSkill
Dependency CVE check (orthogonal to SAST)dep-currency-check
Secrets in code (orthogonal to SAST)secret-scanning
LLM-specific defects (prompt injection, etc.)llm-security
Python web-app auth patternspython-auth-security
The G_SECURE gate this feeds~/.claude/skills/_meta/gates.py
Pre-commit hook patterns (POSIX + Windows hardened PS1)dep-currency-check (precedent)
Bootstrap hook offerinstaller/bootstrap-environment.py
Gespeicherte Skills