Awesome-omni-skill sast-scanning
Perform static application security testing with tools like Semgrep, CodeQL, and SonarQube. Identify security vulnerabilities in source code before deployment. Use when implementing secure SDLC, code review automation, or security gates in CI/CD pipelines.
install
source · Clone the upstream repo
git clone https://github.com/diegosouzapw/awesome-omni-skill
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/diegosouzapw/awesome-omni-skill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/devops/sast-scanning" ~/.claude/skills/diegosouzapw-awesome-omni-skill-sast-scanning-623ed8 && rm -rf "$T"
manifest:
skills/devops/sast-scanning/SKILL.mdsource content
SAST Scanning
Identify security vulnerabilities in source code through static analysis.
When to Use This Skill
Use this skill when:
- Implementing secure SDLC practices
- Adding security gates to CI/CD
- Automating code security reviews
- Finding vulnerabilities before deployment
- Meeting compliance requirements
Prerequisites
- Source code access
- CI/CD pipeline
- SAST tool installation
Tool Comparison
| Tool | License | Languages | Best For |
|---|---|---|---|
| Semgrep | OSS/Commercial | 30+ | Custom rules, speed |
| CodeQL | Free (GitHub) | 10+ | Deep analysis |
| SonarQube | OSS/Commercial | 25+ | Quality + Security |
| Bandit | OSS | Python | Python projects |
| Brakeman | OSS | Ruby | Rails apps |
Semgrep
Installation
# Install via pip pip install semgrep # Or via Homebrew brew install semgrep
Basic Usage
# Run with default rules semgrep --config auto . # Run specific rulesets semgrep --config p/security-audit . semgrep --config p/owasp-top-ten . semgrep --config p/ci . # Scan specific languages semgrep --config p/python . semgrep --config p/javascript . # Output formats semgrep --config auto --json -o results.json . semgrep --config auto --sarif -o results.sarif .
Custom Rules
# .semgrep/custom-rules.yaml rules: - id: hardcoded-password patterns: - pattern-either: - pattern: password = "..." - pattern: PASSWORD = "..." - pattern: passwd = "..." message: Hardcoded password detected severity: ERROR languages: [python, javascript, java] metadata: cwe: "CWE-798" owasp: "A3:2017" - id: sql-injection patterns: - pattern: | $QUERY = "..." + $USER_INPUT + "..." $DB.execute($QUERY) message: Potential SQL injection severity: ERROR languages: [python] metadata: cwe: "CWE-89" - id: insecure-random pattern: random.random() message: Use secrets module for security-sensitive randomness severity: WARNING languages: [python] fix: secrets.token_hex()
CI Configuration
# .github/workflows/semgrep.yml name: Semgrep on: push: branches: [main] pull_request: jobs: semgrep: runs-on: ubuntu-latest container: image: returntocorp/semgrep steps: - uses: actions/checkout@v4 - name: Run Semgrep run: semgrep ci env: SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
CodeQL
Setup
# .github/workflows/codeql.yml name: CodeQL Analysis on: push: branches: [main] pull_request: branches: [main] schedule: - cron: '0 0 * * 0' jobs: analyze: runs-on: ubuntu-latest permissions: security-events: write actions: read contents: read strategy: matrix: language: ['javascript', 'python'] steps: - uses: actions/checkout@v4 - name: Initialize CodeQL uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} queries: +security-and-quality - name: Autobuild uses: github/codeql-action/autobuild@v3 - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 with: category: "/language:${{ matrix.language }}"
Custom Queries
// queries/sql-injection.ql /** * @name SQL Injection * @description User input in SQL query * @kind path-problem * @problem.severity error * @security-severity 9.0 * @precision high * @id py/sql-injection * @tags security */ import python import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import semmle.python.security.dataflow.SqlInjectionQuery from SqlInjectionConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "SQL injection from $@.", source.getNode(), "user input"
SonarQube
Docker Setup
# docker-compose.yml version: '3.8' services: sonarqube: image: sonarqube:lts-community ports: - "9000:9000" environment: - SONAR_JDBC_URL=jdbc:postgresql://db:5432/sonar - SONAR_JDBC_USERNAME=sonar - SONAR_JDBC_PASSWORD=sonar volumes: - sonarqube_data:/opt/sonarqube/data - sonarqube_logs:/opt/sonarqube/logs depends_on: - db db: image: postgres:15 environment: - POSTGRES_USER=sonar - POSTGRES_PASSWORD=sonar - POSTGRES_DB=sonar volumes: - postgresql_data:/var/lib/postgresql/data volumes: sonarqube_data: sonarqube_logs: postgresql_data:
Scanner Configuration
# sonar-project.properties sonar.projectKey=myproject sonar.projectName=My Project sonar.projectVersion=1.0 sonar.sources=src sonar.tests=tests sonar.exclusions=**/node_modules/**,**/vendor/** sonar.language=py sonar.python.coverage.reportPaths=coverage.xml sonar.qualitygate.wait=true
CI Integration
# GitHub Actions - name: SonarQube Scan uses: sonarsource/sonarqube-scan-action@master env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} - name: Quality Gate uses: sonarsource/sonarqube-quality-gate-action@master timeout-minutes: 5 env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
Language-Specific Tools
Python (Bandit)
# Install pip install bandit # Run scan bandit -r src/ -f json -o bandit-report.json # With configuration bandit -r src/ -c bandit.yaml
# bandit.yaml skips: ['B101', 'B601'] exclude_dirs: ['tests', 'venv'] assert_used: skips: ['*_test.py', '*_tests.py']
JavaScript (ESLint Security)
# Install npm install eslint eslint-plugin-security --save-dev
// .eslintrc.js module.exports = { plugins: ['security'], extends: ['plugin:security/recommended'], rules: { 'security/detect-object-injection': 'error', 'security/detect-non-literal-regexp': 'warn', 'security/detect-unsafe-regex': 'error', 'security/detect-buffer-noassert': 'error', 'security/detect-eval-with-expression': 'error', 'security/detect-no-csrf-before-method-override': 'error', 'security/detect-possible-timing-attacks': 'warn' } };
Ruby (Brakeman)
# Install gem install brakeman # Run scan brakeman -o brakeman-report.json -f json # CI configuration brakeman --no-exit-on-warn --no-exit-on-error -o report.html
Quality Gates
SonarQube Quality Gate
{ "name": "Security Gate", "conditions": [ { "metric": "new_security_rating", "op": "GT", "error": "1" }, { "metric": "new_vulnerabilities", "op": "GT", "error": "0" }, { "metric": "new_security_hotspots_reviewed", "op": "LT", "error": "100" } ] }
Custom Gate Script
#!/bin/bash # security-gate.sh CRITICAL=$(cat results.json | jq '[.results[] | select(.severity == "critical")] | length') HIGH=$(cat results.json | jq '[.results[] | select(.severity == "high")] | length') echo "Critical: $CRITICAL, High: $HIGH" if [ "$CRITICAL" -gt 0 ]; then echo "FAILED: Critical vulnerabilities found" exit 1 fi if [ "$HIGH" -gt 5 ]; then echo "FAILED: Too many high severity vulnerabilities" exit 1 fi echo "PASSED: Security gate" exit 0
Common Issues
Issue: Too Many False Positives
Problem: Alerts on safe code patterns Solution: Tune rules, add suppressions, use baseline
Issue: Slow Scans
Problem: SAST taking too long in CI Solution: Incremental scanning, parallel execution, exclude test files
Issue: Missing Coverage
Problem: Vulnerabilities not detected Solution: Add custom rules, combine multiple tools
Best Practices
- Run on every PR/commit
- Establish baseline for existing code
- Prioritize by severity and exploitability
- Maintain custom rules for your codebase
- Integrate with IDE for early feedback
- Track trends over time
- Document false positive suppressions
- Combine with DAST for comprehensive coverage
Related Skills
- dast-scanning - Dynamic testing
- dependency-scanning - Dependency vulnerabilities
- github-actions - CI integration