Static Analysis
Security Notice
AUTHORIZED USE ONLY: These skills are for DEFENSIVE security analysis and authorized research:
-
Authorized security assessments with written permission
-
Code review and quality assurance
-
CI/CD pipeline integration for automated security scanning
-
Compliance validation (SOC2, HIPAA, PCI-DSS)
-
Educational purposes in controlled environments
NEVER use for:
-
Scanning systems without authorization
-
Exploiting discovered vulnerabilities without disclosure
-
Circumventing security controls
-
Any illegal activities
Step 1: Environment Assessment
Before running any analysis, assess the target:
Identify languages in the project
find . -type f -name ".js" -o -name ".ts" -o -name ".py" -o -name ".java" -o -name ".go" -o -name ".c" -o -name ".cpp" -o -name ".cs" -o -name "*.rb" | head -20
Check for existing CodeQL database
ls -la .codeql/ 2>/dev/null || echo "No CodeQL database found"
Check for existing Semgrep config
ls -la .semgrep.yml .semgrep/ 2>/dev/null || echo "No Semgrep config found"
Check for SARIF output directory
ls -la sarif/ results/ 2>/dev/null || echo "No SARIF output directory"
Step 2: CodeQL Analysis
Database Creation
Create CodeQL database for JavaScript/TypeScript
codeql database create codeql-db --language=javascript --source-root=.
Create CodeQL database for Python
codeql database create codeql-db --language=python --source-root=.
Multi-language database
codeql database create codeql-db --language=javascript,python --source-root=.
Running Queries
Run standard security queries
codeql database analyze codeql-db
--format=sarifv2.1.0
--output=results.sarif
codeql/javascript-queries:Security
Run specific query suite
codeql database analyze codeql-db
--format=sarifv2.1.0
--output=results.sarif
codeql/javascript-queries:codeql-suites/javascript-security-and-quality.qls
Run custom query
codeql database analyze codeql-db
--format=sarifv2.1.0
--output=results.sarif
./custom-queries/
Key CodeQL Query Packs
Language Security Pack Quality Pack
JavaScript codeql/javascript-queries:Security
codeql/javascript-queries:Maintainability
Python codeql/python-queries:Security
codeql/python-queries:Maintainability
Java codeql/java-queries:Security
codeql/java-queries:Maintainability
Go codeql/go-queries:Security
codeql/go-queries:Maintainability
C/C++ codeql/cpp-queries:Security
codeql/cpp-queries:Maintainability
Step 3: Semgrep Analysis
Running Semgrep
Run with default rules (auto-detect language)
semgrep scan --config=auto --sarif --output=semgrep-results.sarif
Run with specific rule sets
semgrep scan --config=p/security-audit --sarif --output=semgrep-results.sarif
Run with OWASP Top 10 rules
semgrep scan --config=p/owasp-top-ten --sarif --output=semgrep-results.sarif
Run with multiple rule sets
semgrep scan
--config=p/security-audit
--config=p/owasp-top-ten
--config=p/secrets
--sarif --output=semgrep-results.sarif
Run with custom rules
semgrep scan --config=./semgrep-rules/ --sarif --output=semgrep-results.sarif
Key Semgrep Rule Sets
Rule Set Purpose
p/security-audit
Comprehensive security checks
p/owasp-top-ten
OWASP Top 10 vulnerability checks
p/secrets
Hardcoded secrets detection
p/ci
CI-optimized rule set
p/default
General-purpose rules
p/r2c-security-audit
Trail of Bits security rules
p/javascript
JavaScript-specific rules
p/typescript
TypeScript-specific rules
p/python
Python-specific rules
p/golang
Go-specific rules
Step 4: SARIF Output Processing
SARIF Structure
{ "$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/main/sarif-2.1/schema/sarif-schema-2.1.0.json", "version": "2.1.0", "runs": [{ "tool": { "driver": { "name": "CodeQL", "rules": [...] } }, "results": [{ "ruleId": "js/sql-injection", "level": "error", "message": { "text": "This query depends on a user-provided value." }, "locations": [{ "physicalLocation": { "artifactLocation": { "uri": "src/api/users.js" }, "region": { "startLine": 42, "startColumn": 5 } } }] }] }] }
Parsing SARIF Results
Count findings by severity
jq '[.runs[].results[] | .level] | group_by(.) | map({level: .[0], count: length})' results.sarif
List critical/error findings
jq '.runs[].results[] | select(.level == "error") | {rule: .ruleId, file: .locations[0].physicalLocation.artifactLocation.uri, line: .locations[0].physicalLocation.region.startLine, message: .message.text}' results.sarif
Export findings to CSV
jq -r '.runs[].results[] | [.ruleId, .level, .locations[0].physicalLocation.artifactLocation.uri, .locations[0].physicalLocation.region.startLine, .message.text] | @csv' results.sarif > findings.csv
Step 5: Triage and Reporting
Severity Classification
SARIF Level Severity Action Required
error
CRITICAL/HIGH Immediate fix before merge
warning
MEDIUM Fix within sprint
note
LOW Track and fix when convenient
none
INFORMATIONAL Review and acknowledge
False Positive Assessment
For each finding, evaluate:
-
Data flow: Does user-controlled data actually reach the sink?
-
Sanitization: Is input validated/sanitized before use?
-
Context: Is the vulnerable pattern in test code or production?
-
Reachability: Can the vulnerable code path be triggered?
-
Impact: What is the actual exploitability?
Report Template
Static Analysis Report
Date: YYYY-MM-DD Tools: CodeQL vX.X, Semgrep vX.X Scope: [project/directory]
Summary
| Severity | Count | Fixed | False Positive | Remaining |
|---|---|---|---|---|
| CRITICAL | X | X | X | X |
| HIGH | X | X | X | X |
| MEDIUM | X | X | X | X |
| LOW | X | X | X | X |
Critical Findings
- [Rule ID]: [Description]
- File: [path:line]
- Impact: [description]
- Remediation: [code fix]
Recommendations
- [Prioritized list of actions]
Step 6: CI/CD Integration
GitHub Actions Integration
name: Static Analysis on: [push, pull_request] jobs: codeql: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: github/codeql-action/init@v3 with: languages: javascript - uses: github/codeql-action/analyze@v3 with: output: sarif-results upload: true
semgrep: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: returntocorp/semgrep-action@v1 with: config: >- p/security-audit p/owasp-top-ten generateSarif: '1' - uses: github/codeql-action/upload-sarif@v3 with: sarif_file: semgrep.sarif
OWASP Mapping
OWASP Category CodeQL Queries Semgrep Rules
A01: Broken Access Control Security/CWE-284
p/owasp-top-ten
A02: Cryptographic Failures Security/CWE-327
p/secrets
A03: Injection Security/CWE-089 , CWE-078
p/security-audit
A07: Auth Failures Security/CWE-287
p/owasp-top-ten
A09: Logging Failures Security/CWE-117
p/security-audit
A10: SSRF Security/CWE-918
p/owasp-top-ten
Related Skills
-
variant-analysis
-
Pattern-based vulnerability discovery across codebases
-
semgrep-rule-creator
-
Custom Semgrep rule development
-
differential-review
-
Security-focused diff analysis
-
insecure-defaults
-
Hardcoded credentials and fail-open detection
-
security-architect
-
STRIDE threat modeling and OWASP Top 10
-
code-analyzer
-
Code metrics and complexity analysis
Agent Integration
-
security-architect (primary): Security assessments and threat modeling
-
code-reviewer (secondary): Automated code review augmentation
-
penetration-tester (secondary): Vulnerability verification
-
qa (secondary): Quality gate enforcement
Iron Laws
-
NEVER deploy to production without running both Semgrep and CodeQL analysis
-
ALWAYS create a fresh CodeQL database — stale databases miss recently added code
-
NEVER suppress a finding without documenting the false positive rationale in a code comment
-
ALWAYS block on CRITICAL/HIGH findings in CI/CD; never merge with unresolved critical issues
-
NEVER run analysis on test/fixture directories — always exclude non-production code paths
Anti-Patterns
Anti-Pattern Why It Fails Correct Approach
Using outdated CodeQL database Analysis misses code added since last build Always create a fresh database before each analysis run
Using generic rule suites Generic rules miss language-specific security patterns Use language-specific security suites (e.g., codeql/javascript-queries:Security )
Suppressing findings without rationale Creates silent security debt and audit gaps Document false positive reason in code comment before suppressing
Scanning test/fixture code False positives from intentionally vulnerable test code Exclude test/ and fixture/ directories from all scans
Not re-running after fixes Remediation not confirmed; same finding recurs Always re-run analysis after each fix to verify resolution
Memory Protocol (MANDATORY)
Before starting: Read .claude/context/memory/learnings.md
After completing:
-
New pattern -> .claude/context/memory/learnings.md
-
Issue found -> .claude/context/memory/issues.md
-
Decision made -> .claude/context/memory/decisions.md
ASSUME INTERRUPTION: If it's not in memory, it didn't happen.