From security-research
Run Semgrep static analysis scans on target source code. Supports registry rule packs(security-audit, owasp-top-ten, secrets), custom taint rule writing, and structured JSON output parsing. Use when performing SAST scanning, writing taint analysis rules, hunting for vulnerabilities with pattern matching, or running automated security scans during any audit phase.
npx claudepluginhub pucagit/claude-plugin --plugin security-researchThis skill uses the workspace's default tool permissions.
Run Semgrep against `$ARGUMENTS`.
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
Run Semgrep against $ARGUMENTS.
Ensure semgrep is installed:
source /home/kali/.venv/bin/activate
if ! command -v semgrep &> /dev/null; then
pip3 install semgrep
fi
semgrep --version
Parse $ARGUMENTS to determine mode:
scan — Registry ScanRun pre-built security rules from the Semgrep registry.
# Determine target language from file extensions
# Choose appropriate config packs
semgrep scan \
--config p/security-audit \
--config p/owasp-top-ten \
--config p/secrets \
--json --output ${AUDIT_DIR:-./}/logs/semgrep-registry.json \
--severity WARNING --severity ERROR \
--dataflow-traces \
--timeout 10 \
--max-target-bytes 2000000 \
--exclude "vendor" --exclude "node_modules" --exclude "*.min.js" \
${TARGET_PATH}
Add language-specific packs based on what's detected:
| Language | Pack |
|---|---|
| Python | p/python |
| JavaScript | p/javascript |
| TypeScript | p/typescript |
| Java | p/java |
| Go | p/go |
| PHP | p/php |
| Ruby | p/ruby |
| Rust | p/rust |
| C/C++ | p/c |
| C# | p/csharp |
Additional security-focused packs: p/xss, p/sql-injection, p/command-injection, p/jwt, p/insecure-transport, p/supply-chain.
rule — Write Custom RulesWrite target-specific Semgrep rules. See rule-syntax.md for the complete YAML schema and pattern syntax reference.
Basic rule structure:
rules:
- id: unique-rule-id
message: "What was found and why it matters"
severity: ERROR # ERROR, WARNING, INFO
languages: [python]
pattern: dangerous_function($USER_INPUT)
metadata:
cwe: CWE-XXX
confidence: HIGH
Key pattern operators:
pattern — match code directlypatterns — AND logic (all must match)pattern-either — OR logic (any can match)pattern-not — exclude matchespattern-inside — require enclosing contextpattern-regex — PCRE2 regex matching$X — metavariable capturing any expression... — ellipsis matching zero or more items<... P ...> — deep expression matchingValidate before running:
semgrep --validate --config ${AUDIT_DIR}/logs/semgrep-rules/
taint — Taint AnalysisWrite taint tracking rules that follow data from sources to sinks. See taint-rules.md for pre-built rules covering SQLi, CMDi, SSRF, path traversal, XSS, and deserialization.
Taint rule structure:
rules:
- id: taint-rule-id
mode: taint # Required for taint analysis
message: "Tainted data reaches dangerous sink"
severity: ERROR
languages: [python]
pattern-sources:
- pattern: request.args.get(...)
pattern-sanitizers:
- pattern: sanitize($X)
pattern-sinks:
- pattern: cursor.execute($QUERY)
When writing target-specific taint rules:
${AUDIT_DIR}/logs/semgrep-rules/sweep — Full Security SweepCombined registry + custom taint rules:
# Step 1: Registry scan
semgrep scan \
--config p/security-audit \
--config p/owasp-top-ten \
--config p/secrets \
--config p/${LANGUAGE} \
--json --output ${AUDIT_DIR}/logs/semgrep-registry.json \
--severity WARNING --severity ERROR \
--dataflow-traces \
--timeout 10 \
--max-target-bytes 2000000 \
${TARGET_SOURCE}
# Step 2: Custom taint rules (if they exist)
if [ -d "${AUDIT_DIR}/logs/semgrep-rules" ] && [ "$(ls -A ${AUDIT_DIR}/logs/semgrep-rules/*.yaml 2>/dev/null)" ]; then
semgrep scan \
--config ${AUDIT_DIR}/logs/semgrep-rules/ \
--json --output ${AUDIT_DIR}/logs/semgrep-custom.json \
--dataflow-traces \
--timeout 15 \
${TARGET_SOURCE}
fi
{
"results": [{
"check_id": "rule-id",
"path": "file/path.py",
"start": {"line": 10, "col": 5},
"end": {"line": 10, "col": 42},
"extra": {
"message": "Description",
"severity": "ERROR",
"metadata": { "cwe": ["CWE-89"], "confidence": "HIGH" },
"dataflow_trace": { "taint_source": [...], "taint_sink": [...] },
"lines": "matching source code"
}
}]
}
| Semgrep Field | Audit Field |
|---|---|
check_id | Reference ID |
extra.severity | Severity (ERROR→HIGH, WARNING→MEDIUM) |
path + start.line | Location (file:line) |
extra.metadata.cwe | CWE classification |
extra.lines | Vulnerable code snippet |
extra.dataflow_trace | Source → Sink chain |
Tag all Semgrep findings for traceability:
[SEMGREP:rule-id] — detected by Semgrep[MANUAL-DETECTED] — found by manual review[SEMGREP+MANUAL] — confirmed by both (highest confidence)| Flag | Default | Recommendation |
|---|---|---|
--jobs | 0.85x CPUs | Default is fine |
--timeout | 5s | 10-15s for complex taint rules |
--max-target-bytes | 1MB | 2MB for large files |
--exclude | none | Always exclude vendor/, node_modules/ |
| Code | Meaning |
|---|---|
| 0 | No findings |
| 1 | Findings detected — parse results |
| 2 | Fatal error |
| 4 | Invalid rule pattern — validate rules |
| 5 | Unparseable YAML — fix syntax |
| 7 | Config not found |
| Phase | Semgrep Task | Config |
|---|---|---|
| Phase 1 (Recon) | Secret detection | p/secrets |
| Phase 2 (Code Review) | Dataflow trace bootstrap | p/security-audit --dataflow-traces |
| Phase 3 (Vuln Detection) | Full scan + custom rules | Registry + custom YAML |
Semgrep supplements manual analysis. It cannot catch: