---
name: semgrep-appsec
description: "Semgrep SAST and supply-chain SCA — custom rules, taint mode, reachability, PR scanning, OWASP triage. Production Semgrep AppSec: writing custom rules with patterns, pattern-either/pattern-inside/metavariables and autofix; taint mode with sources/sinks/sanitizers and pattern-propagators for dataflow analysis; semgrep ci with diff-aware PR scanning and baseline; reachability-based Supply Chain (SCA) to filter unreachable transitive deps; the Registry, p/owasp-top-ten and p/default rulesets, .semgrepignore, nosemgrep, and SARIF output for GitHub Actions and code scanning."
license: MIT
---

# Semgrep AppSec Pro

A focused toolkit for running Semgrep as a real application-security program: authoring custom rules, modeling dataflow with taint mode, gating pull requests with diff-aware scans, and triaging findings against OWASP categories. Built for AppSec engineers and platform teams who have outgrown the default registry rulepacks and need rules tuned to their own frameworks, sinks, and false-positive patterns.

## When to use it

- You keep getting noisy or missed findings from `p/default` and want rules that match your codebase's actual API surface.
- You need to trace untrusted input from an HTTP handler to a dangerous sink (SQL, `exec`, deserialization) instead of grepping for the sink alone.
- CI is slow because every PR re-scans the whole repo and you want to surface only newly introduced issues.
- You're prioritizing a backlog and need findings mapped to OWASP Top 10 with reachability context from dependencies.

## How it works

Rules are YAML with `pattern`, `pattern-either`, `pattern-inside`, `pattern-not`, and `metavariables` (`$X`) for syntactic matching, plus `metavariable-pattern` and `metavariable-regex` for refinement. Add a `fix:` key for autofix. Run locally with `semgrep scan --config rule.yaml`.

Taint mode (`mode: taint`) does interprocedural dataflow with `pattern-sources`, `pattern-sinks`, `pattern-sanitizers`, and `pattern-propagators` to follow tainted values across assignments and function calls.

In CI, `semgrep ci` is diff-aware: against a baseline (`--baseline-commit`) it reports only findings introduced by the changeset, posts inline PR comments via the App, and exits non-zero to block merges. Supply Chain (SCA) parses lockfiles and uses reachability analysis to flag whether a vulnerable dependency function is actually called.

## Usage

```bash
curl -fsSL --create-dirs -o ~/.claude/skills/semgrep-appsec/SKILL.md https://claudeskil.com/skills/semgrep-appsec/SKILL.md

# Taint rule: user input reaching a raw SQL sink
cat > rules/sqli.yaml <<'YAML'
rules:
  - id: tainted-sql
    mode: taint
    pattern-sources:
      - pattern: flask.request.$ANY
    pattern-sinks:
      - pattern: $CURSOR.execute(...)
    pattern-sanitizers:
      - pattern: sqlalchemy.text(...)
    message: Untrusted input reaches SQL execution
    languages: [python]
    severity: ERROR
YAML

semgrep scan --config rules/sqli.yaml --sarif -o results.sarif
semgrep ci --baseline-commit origin/main   # PR gate
```

## Tips & gotchas

- Validate rules with `semgrep --test` against `.yaml` fixtures using `# ruleid:` and `# ok:` annotations before shipping.
- `pattern-inside` scopes a match to a context (e.g., inside a route handler); `pattern-not-inside` is how you kill whole classes of false positives.
- Taint sanitizers must match the exact node — wrapping the sanitizer in another call can let taint slip through; add a `pattern-propagators` entry if a helper passes taint along.
- Reachability/SCA needs lockfiles (`poetry.lock`, `package-lock.json`, etc.) committed; manifest-only repos fall back to non-reachable matching.

## FAQ

**Do I need a Semgrep account?** Local `semgrep scan` and OSS rules work offline. Diff-aware PR comments, managed policies, and reachability SCA require connecting to Semgrep AppSec Platform with `SEMGREP_APP_TOKEN`.

**Why does my pattern miss obvious cases?** Patterns match the parsed AST, not text. Use `semgrep --dump-ast` to see how code parses, and prefer `pattern-either` over brittle regex.

**Can I autofix in CI?** Yes — rules with a `fix:` field support `semgrep ci --autofix`, but review generated diffs since fixes are syntactic, not semantic.
