Skip to content

Opengrep - Open-Source Static Code Analysis Cheatsheet

Opengrep - Open-Source Static Code Analysis Cheatsheet

Opengrep is a community-governed fork of the Semgrep engine, created after features moved behind a commercial license. It performs fast, pattern-based static application security testing (SAST) across 30+ languages, using rules written in a syntax that looks like the code being matched — no AST expertise required. The fork’s premise is that core scanning capability (including features like cross-file dataflow) should remain fully open-source.

Installation

MethodCommand
Install script`curl -fsSL https://raw.githubusercontent.com/opengrep/opengrep/main/install.sh
Dockerdocker run --rm -v "$PWD:/src" opengrep/opengrep opengrep scan /src
Binarydownload from GitHub Releases
Verifyopengrep --version

Scanning

CommandDescription
opengrep scan .Scan the current directory with default rules
opengrep scan --config auto .Auto-select rules for detected languages
opengrep scan --config rules/ .Use a local rule directory
opengrep scan --config p/security-audit .Use a rule pack
opengrep scan --json -o out.json .JSON output
opengrep scan --sarif -o out.sarif .SARIF for code-scanning platforms

Writing Rules

Rules are YAML; the pattern looks like the code you want to find.

rules:
  - id: hardcoded-aws-key
    patterns:
      - pattern: $KEY = "AKIA..."
    message: Possible hardcoded AWS access key
    languages: [python, javascript]
    severity: ERROR
KeyPurpose
patternCode shape to match ($X = metavariable)
patternsAND of several conditions
pattern-eitherOR of alternatives
pattern-notExclude a shape (kill false positives)
pattern-insideOnly match within a context
metavariable-regexConstrain a metavariable
severityINFO / WARNING / ERROR

Pattern Syntax Essentials

SyntaxMatches
$XAny single expression (metavariable)
...Any sequence (args, statements)
foo(...)Any call to foo
$OBJ.method(...)Method call on anything
"..."Any string literal
# Find eval() on any non-literal input
- pattern: eval($X)
  pattern-not: eval("...")

Taint / Dataflow Rules

rules:
  - id: sqli-taint
    mode: taint
    pattern-sources:
      - pattern: request.args.get(...)
    pattern-sinks:
      - pattern: cursor.execute($Q)
    message: Untrusted input reaches SQL execution
    languages: [python]
    severity: ERROR

Taint mode tracks data from sources (untrusted input) to sinks (dangerous operations), which is how you find real injection bugs rather than syntactic look-alikes.

CI Integration

# Fail the build on ERROR-severity findings
opengrep scan --config auto --error .

# Only scan files changed in this PR
opengrep scan --config auto --baseline-commit origin/main .
FlagEffect
--errorNon-zero exit when findings exist
--baseline-commitDiff-aware scanning (new findings only)
--severity ERRORFilter by severity
--excludeSkip paths (vendor, tests)
--sarifUpload to GitHub code scanning

Testing Rules

# Rules ship with test files annotated with expected findings
opengrep test rules/

Annotate a test file with # ruleid: my-rule above a line that should match and # ok: my-rule where it should not — then opengrep test verifies the rule behaves.

AspectOpengrepSemgrepCodeQL
LicenseFully open-sourceOpen core + commercialFree for OSS, restricted commercial
Rule syntaxCode-like patternsSame lineageQL query language
Learning curveLowLowHigh
Best forOpen SAST without feature gatingManaged platform + rulesDeep semantic queries

Pairs with Semgrep knowledge (rules are largely compatible) and complements Bandit for Python-specific checks.

Resources