Security Review Patterns
SAST Tools
Semgrep (language-agnostic)
# Install
pip install semgrep
# Run with OWASP ruleset
semgrep --config=p/owasp-top-ten .
semgrep --config=p/secrets .
semgrep --config=p/python .
# Custom rule
cat > no-hardcoded-secrets.yaml << 'EOF'
rules:
- id: hardcoded-api-key
pattern: api_key = "..."
message: Hardcoded API key detected
severity: ERROR
languages: [python, javascript]
EOF
semgrep --config=no-hardcoded-secrets.yaml .
Bandit (Python)
pip install bandit
bandit -r src/ -ll -ii # Only medium+ severity, medium+ confidence
bandit -r src/ -f json -o bandit-report.json
bandit -r src/ --skip B101,B601 # Skip assert and shell injection in tests
CodeQL
# .github/workflows/codeql.yml
name: CodeQL
on: [push, pull_request]
jobs:
analyze:
runs-on: ubuntu-latest
permissions:
security-events: write
steps:
- uses: actions/checkout@v4
- uses: github/codeql-action/init@v3
with:
languages: python, javascript
- uses: github/codeql-action/autobuild@v3
- uses: github/codeql-action/analyze@v3
Dependency Scanning
# Python
pip-audit # Checks PyPI advisories
safety check -r requirements.txt
# Node.js
npm audit --audit-level=moderate
npx better-npm-audit audit
# Go
govulncheck ./...
# Rust
cargo audit
# Java
mvn org.owasp:dependency-check-maven:check
Secrets Detection
# Gitleaks — scan repo history
brew install gitleaks
gitleaks detect --source . -v
gitleaks detect --source . --log-opts="HEAD~5..HEAD"
# Pre-commit hook
pip install detect-secrets
detect-secrets scan > .secrets.baseline
detect-secrets audit .secrets.baseline
# TruffleHog
trufflehog git file://. --since-commit HEAD~10 --only-verified
Review Checklist
Input Validation
- All user-supplied data validated at boundaries
- SQL queries use parameterized statements
- File paths sanitized against traversal (
../) - XML/JSON inputs limit size and depth
- Regular expressions protected against ReDoS
Authentication & Authorization
- Passwords hashed with bcrypt/argon2 (never MD5/SHA1)
- JWT expiry set, signature verified, alg pinned
- Session IDs regenerated after login
- IDOR prevented — object ownership verified server-side
- Sensitive endpoints require re-authentication
Cryptography
- No custom crypto implementations
- TLS 1.2+ enforced, weak ciphers disabled
- Secrets not logged or included in error responses
- Random values use
secrets/crypto.randomBytes
Output Encoding
- HTML output escaped (XSS prevention)
-
Content-Typeheaders set correctly - JSON responses set
application/json(nottext/html)
Triage Severity Matrix
| Finding | Severity | Action |
|---|---|---|
| SQL injection, RCE | Critical | Block merge, fix immediately |
| Auth bypass, IDOR | High | Fix before release |
| Hardcoded secret | High | Rotate + fix |
| Missing rate limit | Medium | Fix in sprint |
| Verbose error messages | Low | Schedule cleanup |
CI Integration
# GitHub Actions security gate
- name: Run Semgrep
run: semgrep --config=p/owasp-top-ten --error .
- name: Audit dependencies
run: pip-audit --fail-on-vuln
- name: Check for secrets
run: gitleaks detect --source . --exit-code 1