CloudOpsGuide
devsecops

SAST Tools: Static Application Security Testing

Intermediate
14 minutes
October 2026
CloudOpsGuide Team

SAST Tools: Static Application Security Testing

Compare and implement SAST tools — SonarQube, Semgrep, Snyk, and CodeQL — in your CI/CD pipeline.

Table of Contents

What SAST Does

SAST analyzes source code (or compiled binaries) without running it to find:

  • SQL injection, XSS, command injection
  • Hardcoded credentials and secrets
  • Insecure crypto usage
  • Buffer overflows (C/C++)
  • Framework-specific misconfigurations

It runs fast and early — catch bugs before code review, not in production.

Tool Comparison

ToolTypeLanguagesBest ForFree Tier
SonarQubeServer + scanner30+Teams wanting dashboardsCommunity edition
SemgrepCLI rules engine30+Custom rules, fast CIOpen source
CodeQLGitHub-native9GitHub repos, deep analysisFree on public repos
SnykCloud SaaSManyDev-first UX, fix adviceLimited free scans
CheckmarxEnterprise SaaS35+Compliance-heavy orgsTrial only
BanditCLIPython onlyPython projectsOpen source
GitleaksCLI secretsAny textSecrets detectionOpen source

Quick Start Guides

Semgrep (Fastest to Set Up)

# Install
pip install semgrep

# Scan with community rules
semgrep scan --config auto .

# Scan with specific ruleset
semgrep scan --config p/security-audit .

CI-friendly — one command, JSON output, exit code reflects findings.

SonarQube

# Start local SonarQube
docker run -d -p 9000:9000 sonarqube:community

# Scan with sonar-scanner
sonar-scanner \
  -Dsonar.projectKey=my-app \
  -Dsonar.sources=. \
  -Dsonar.host.url=http://localhost:9000 \
  -Dsonar.login=$SONAR_TOKEN

CodeQL (GitHub Native)

# .github/workflows/codeql.yml
name: "CodeQL"
on: [push, pull_request]
jobs:
  analyze:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: github/codeql-action/init@v3
        with:
          languages: javascript-typescript
      - uses: github/codeql-action/analyze@v3

Bandit (Python)

pip install bandit
bandit -r . -f json -o bandit-report.json

CI/CD Integration

Jenkins Pipeline

stage('SAST Scan') {
    steps {
        sh '''
            semgrep scan --config auto . \
              --json -o semgrep-results.json || true
        '''
        archiveArtifacts 'semgrep-results.json'
    }
}

GitHub Actions

- name: Run Semgrep
  uses: semgrep/semgrep-action@v1
  with:
    config: p/security-audit
    generateSarif: true
- name: Upload SARIF
  uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: semgrep.sarif

Quality Gate

# Block merges on new critical findings
- name: Check findings
  run: |
    CRITICAL=$(jq '[.results[] | select(.extra.severity == "ERROR")] | length' report.json)
    if [ "$CRITICAL" -gt 0 ]; then
      echo "::error::$CRITICAL critical findings"
      exit 1
    fi

Triage and Baseline

First scan on a legacy codebase will show hundreds of findings. Don't panic:

Step 1: Baseline

# Accept current state, only flag new issues
semgrep scan --config auto --baseline-commit main .

Step 2: Suppress False Positives

# Inline suppression with justification
query = f"SELECT * FROM users WHERE id = {user_id}"  # nosemgrep: user input validated upstream

Step 3: Custom Rules

# rules/no-eval.yml — block eval() in your codebase
rules:
  - id: no-eval
    pattern: eval(...)
    message: "eval() is banned in this codebase"
    severity: ERROR
    languages: [python, javascript]
semgrep scan --config rules/ .

Best Practices

1. Scan Every PR, Not Just Main

on: [push, pull_request]    # catch issues before merge

2. Combine SAST with Other Scans

LayerTool Type
Code quality + vulnsSAST (Semgrep/SonarQube)
SecretsGitleaks, TruffleHog
DependenciesSnyk, Dependabot, npm audit
ContainersTrivy
RuntimeDAST (OWASP ZAP)

3. Tune Severity, Don't Disable

Disable noisy rules rather than whole scans:

# .semgrepignore
tests/
migrations/
*.min.js

4. Track Metrics Over Time

  • Findings per KLOC trending down = healthy
  • Mean time to remediate < 30 days
  • Zero critical findings older than SLA

5. Developer-Friendly Output

# Human-readable summary, not just JSON
semgrep scan --config auto . --output report.txt

Common Pitfalls

  • Scanning everything every commit — scope to changed files with --baseline-commit
  • No baseline on legacy code — drowning in old findings kills adoption
  • SAST alone — misses runtime issues; pair with DAST and dependency scanning
  • Ignoring developer feedback — tune rules quarterly based on false-positive reports

Related Articles


Last Updated: October 2026
Author: CloudOpsGuide Team
Difficulty: Intermediate
Estimated Reading Time: 14 minutes