Files
DevOps-Security-Agent-Skills/security/scanning/sast-scanning/SKILL.md
T

420 lines
8.6 KiB
Markdown
Raw Normal View History

2026-01-27 17:35:45 -05:00
---
name: sast-scanning
description: 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.
license: MIT
metadata:
author: devops-skills
version: "1.0"
---
# 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
```bash
# Install via pip
pip install semgrep
# Or via Homebrew
brew install semgrep
```
### Basic Usage
```bash
# 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
```yaml
# .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
```yaml
# .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
```yaml
# .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
```ql
// 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
```yaml
# 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
```properties
# 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
```yaml
# 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)
```bash
# Install
pip install bandit
# Run scan
bandit -r src/ -f json -o bandit-report.json
# With configuration
bandit -r src/ -c bandit.yaml
```
```yaml
# bandit.yaml
skips: ['B101', 'B601']
exclude_dirs: ['tests', 'venv']
assert_used:
skips: ['*_test.py', '*_tests.py']
```
### JavaScript (ESLint Security)
```bash
# Install
npm install eslint eslint-plugin-security --save-dev
```
```javascript
// .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)
```bash
# 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
```json
{
"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
```bash
#!/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](../dast-scanning/) - Dynamic testing
- [dependency-scanning](../dependency-scanning/) - Dependency vulnerabilities
- [github-actions](../../../devops/ci-cd/github-actions/) - CI integration