mirror of
https://github.com/BagelHole/DevOps-Security-Agent-Skills.git
synced 2026-08-22 12:49:53 +02:00
.
This commit is contained in:
@@ -0,0 +1,391 @@
|
||||
---
|
||||
name: container-scanning
|
||||
description: Scan container images for vulnerabilities using Trivy, Grype, and cloud-native tools. Identify security issues in base images, packages, and configurations. Use when implementing container security, building secure images, or meeting compliance requirements.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# Container Scanning
|
||||
|
||||
Scan container images for vulnerabilities and security misconfigurations.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when:
|
||||
- Building container images
|
||||
- Implementing container security gates
|
||||
- Scanning registry images
|
||||
- Meeting compliance requirements
|
||||
- Hardening container deployments
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Container runtime (Docker, Podman)
|
||||
- Container images to scan
|
||||
- Scanning tool installation
|
||||
|
||||
## Tool Comparison
|
||||
|
||||
| Tool | License | Speed | Features |
|
||||
|------|---------|-------|----------|
|
||||
| Trivy | OSS | Fast | Comprehensive, IaC |
|
||||
| Grype | OSS | Fast | Accurate, SBOM |
|
||||
| Clair | OSS | Medium | Registry integration |
|
||||
| Snyk Container | Commercial | Fast | Fix suggestions |
|
||||
| Docker Scout | Commercial | Fast | GitHub integration |
|
||||
|
||||
## Trivy
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
# Linux
|
||||
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin
|
||||
|
||||
# macOS
|
||||
brew install trivy
|
||||
|
||||
# Docker
|
||||
docker pull aquasec/trivy
|
||||
```
|
||||
|
||||
### Image Scanning
|
||||
|
||||
```bash
|
||||
# Scan local image
|
||||
trivy image myapp:latest
|
||||
|
||||
# Scan remote image
|
||||
trivy image nginx:1.25
|
||||
|
||||
# JSON output
|
||||
trivy image --format json -o results.json myapp:latest
|
||||
|
||||
# Filter by severity
|
||||
trivy image --severity HIGH,CRITICAL myapp:latest
|
||||
|
||||
# Ignore unfixed vulnerabilities
|
||||
trivy image --ignore-unfixed myapp:latest
|
||||
|
||||
# Exit code on vulnerability
|
||||
trivy image --exit-code 1 --severity CRITICAL myapp:latest
|
||||
```
|
||||
|
||||
### Filesystem Scanning
|
||||
|
||||
```bash
|
||||
# Scan project directory
|
||||
trivy fs /path/to/project
|
||||
|
||||
# Scan Dockerfile
|
||||
trivy config Dockerfile
|
||||
|
||||
# Scan Kubernetes manifests
|
||||
trivy config k8s/
|
||||
```
|
||||
|
||||
### Configuration
|
||||
|
||||
```yaml
|
||||
# trivy.yaml
|
||||
timeout: 10m
|
||||
severity:
|
||||
- HIGH
|
||||
- CRITICAL
|
||||
ignore-unfixed: true
|
||||
exit-code: 1
|
||||
|
||||
vulnerability:
|
||||
type:
|
||||
- os
|
||||
- library
|
||||
|
||||
scan:
|
||||
file-patterns:
|
||||
- "Dockerfile"
|
||||
- "*.yaml"
|
||||
```
|
||||
|
||||
### CI Integration
|
||||
|
||||
```yaml
|
||||
# GitHub Actions
|
||||
name: Container Security
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
scan:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build image
|
||||
run: docker build -t myapp:${{ github.sha }} .
|
||||
|
||||
- name: Run Trivy
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
image-ref: 'myapp:${{ github.sha }}'
|
||||
format: 'sarif'
|
||||
output: 'trivy-results.sarif'
|
||||
severity: 'CRITICAL,HIGH'
|
||||
exit-code: '1'
|
||||
|
||||
- name: Upload results
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
with:
|
||||
sarif_file: 'trivy-results.sarif'
|
||||
```
|
||||
|
||||
## Grype
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
# Linux/macOS
|
||||
curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin
|
||||
|
||||
# Homebrew
|
||||
brew install grype
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
# Scan image
|
||||
grype myapp:latest
|
||||
|
||||
# Scan from SBOM
|
||||
grype sbom:./sbom.json
|
||||
|
||||
# JSON output
|
||||
grype myapp:latest -o json > results.json
|
||||
|
||||
# Filter severity
|
||||
grype myapp:latest --fail-on high
|
||||
|
||||
# Scan directory
|
||||
grype dir:/path/to/project
|
||||
```
|
||||
|
||||
### Configuration
|
||||
|
||||
```yaml
|
||||
# .grype.yaml
|
||||
check-for-app-update: false
|
||||
fail-on-severity: high
|
||||
output: "json"
|
||||
scope: "Squashed"
|
||||
|
||||
ignore:
|
||||
- vulnerability: CVE-2023-12345
|
||||
reason: "False positive"
|
||||
expires: "2024-12-31"
|
||||
```
|
||||
|
||||
## Docker Scout
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
# Enable Docker Scout
|
||||
docker scout quickview myapp:latest
|
||||
|
||||
# Full CVE report
|
||||
docker scout cves myapp:latest
|
||||
|
||||
# Compare images
|
||||
docker scout compare myapp:v1 myapp:v2
|
||||
|
||||
# Recommendations
|
||||
docker scout recommendations myapp:latest
|
||||
```
|
||||
|
||||
### CI Integration
|
||||
|
||||
```yaml
|
||||
- name: Docker Scout
|
||||
uses: docker/scout-action@v1
|
||||
with:
|
||||
command: cves
|
||||
image: ${{ env.IMAGE_NAME }}
|
||||
sarif-file: scout-results.sarif
|
||||
summary: true
|
||||
```
|
||||
|
||||
## Registry Integration
|
||||
|
||||
### Amazon ECR
|
||||
|
||||
```bash
|
||||
# Enable scan on push
|
||||
aws ecr put-image-scanning-configuration \
|
||||
--repository-name myapp \
|
||||
--image-scanning-configuration scanOnPush=true
|
||||
|
||||
# Get scan findings
|
||||
aws ecr describe-image-scan-findings \
|
||||
--repository-name myapp \
|
||||
--image-id imageTag=latest
|
||||
|
||||
# Start manual scan
|
||||
aws ecr start-image-scan \
|
||||
--repository-name myapp \
|
||||
--image-id imageTag=latest
|
||||
```
|
||||
|
||||
### Azure ACR
|
||||
|
||||
```bash
|
||||
# Enable Defender for Containers
|
||||
az security pricing create \
|
||||
--name Containers \
|
||||
--tier Standard
|
||||
|
||||
# View scan results in Azure Portal or:
|
||||
az acr repository show \
|
||||
--name myregistry \
|
||||
--image myapp:latest
|
||||
```
|
||||
|
||||
### Google Artifact Registry
|
||||
|
||||
```bash
|
||||
# Enable vulnerability scanning
|
||||
gcloud artifacts repositories update myrepo \
|
||||
--location=us-central1 \
|
||||
--enable-vulnerability-scanning
|
||||
|
||||
# View vulnerabilities
|
||||
gcloud artifacts docker images describe \
|
||||
us-central1-docker.pkg.dev/project/myrepo/myapp:latest \
|
||||
--show-package-vulnerability
|
||||
```
|
||||
|
||||
## Admission Controllers
|
||||
|
||||
### OPA Gatekeeper
|
||||
|
||||
```yaml
|
||||
apiVersion: templates.gatekeeper.sh/v1beta1
|
||||
kind: ConstraintTemplate
|
||||
metadata:
|
||||
name: k8sallowedrepos
|
||||
spec:
|
||||
crd:
|
||||
spec:
|
||||
names:
|
||||
kind: K8sAllowedRepos
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
properties:
|
||||
repos:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
targets:
|
||||
- target: admission.k8s.gatekeeper.sh
|
||||
rego: |
|
||||
package k8sallowedrepos
|
||||
|
||||
violation[{"msg": msg}] {
|
||||
container := input.review.object.spec.containers[_]
|
||||
satisfied := [good | repo = input.parameters.repos[_]; good = startswith(container.image, repo)]
|
||||
not any(satisfied)
|
||||
msg := sprintf("container <%v> has an invalid image repo <%v>", [container.name, container.image])
|
||||
}
|
||||
```
|
||||
|
||||
### Kyverno
|
||||
|
||||
```yaml
|
||||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: require-image-scan
|
||||
spec:
|
||||
validationFailureAction: enforce
|
||||
rules:
|
||||
- name: check-vulnerabilities
|
||||
match:
|
||||
resources:
|
||||
kinds:
|
||||
- Pod
|
||||
verifyImages:
|
||||
- image: "*"
|
||||
attestations:
|
||||
- predicateType: cosign.sigstore.dev/attestation/vuln/v1
|
||||
conditions:
|
||||
- all:
|
||||
- key: "{{ scanner.result.summary.criticalCount }}"
|
||||
operator: Equals
|
||||
value: "0"
|
||||
```
|
||||
|
||||
## Scanning Policies
|
||||
|
||||
### Policy Definition
|
||||
|
||||
```yaml
|
||||
# scan-policy.yaml
|
||||
policies:
|
||||
- name: critical-vulnerabilities
|
||||
description: Block images with critical CVEs
|
||||
severity: CRITICAL
|
||||
action: block
|
||||
|
||||
- name: high-vulnerabilities
|
||||
description: Warn on high severity CVEs
|
||||
severity: HIGH
|
||||
action: warn
|
||||
max_count: 5
|
||||
|
||||
- name: age-policy
|
||||
description: Block images older than 30 days
|
||||
max_age_days: 30
|
||||
action: block
|
||||
|
||||
- name: base-image
|
||||
description: Only allow approved base images
|
||||
allowed_bases:
|
||||
- alpine:3.18
|
||||
- ubuntu:22.04
|
||||
- python:3.11-slim
|
||||
```
|
||||
|
||||
## Common Issues
|
||||
|
||||
### Issue: False Positives
|
||||
**Problem**: Scanner reports non-exploitable vulnerabilities
|
||||
**Solution**: Use ignore files, validate with context
|
||||
|
||||
### Issue: Slow Scans
|
||||
**Problem**: Scanning takes too long
|
||||
**Solution**: Use caching, scan incrementally, optimize image layers
|
||||
|
||||
### Issue: Unfixed Vulnerabilities
|
||||
**Problem**: No patch available for CVE
|
||||
**Solution**: Update base image, implement compensating controls
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Scan in CI/CD pipeline
|
||||
- Use minimal base images (Alpine, distroless)
|
||||
- Update base images regularly
|
||||
- Implement admission control
|
||||
- Track vulnerabilities over time
|
||||
- Set severity thresholds
|
||||
- Document accepted risks
|
||||
- Use multi-stage builds
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [docker-management](../../../devops/containers/docker-management/) - Container basics
|
||||
- [container-hardening](../../hardening/container-hardening/) - Security hardening
|
||||
- [kubernetes-hardening](../../hardening/kubernetes-hardening/) - K8s security
|
||||
@@ -0,0 +1,399 @@
|
||||
---
|
||||
name: dast-scanning
|
||||
description: Perform dynamic application security testing with OWASP ZAP, Burp Suite, and Nikto. Test running applications for security vulnerabilities through automated and manual testing. Use when testing web applications, APIs, or performing penetration testing.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# DAST Scanning
|
||||
|
||||
Test running applications for security vulnerabilities through dynamic analysis.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when:
|
||||
- Testing deployed applications
|
||||
- Performing automated security scans
|
||||
- Finding runtime vulnerabilities
|
||||
- Testing authentication flows
|
||||
- Validating API security
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Running application instance
|
||||
- Network access to target
|
||||
- Testing authorization
|
||||
- Understanding of web security
|
||||
|
||||
## Tool Overview
|
||||
|
||||
| Tool | Type | Best For |
|
||||
|------|------|----------|
|
||||
| OWASP ZAP | OSS | Automated scanning, CI |
|
||||
| Burp Suite | Commercial | Manual testing, advanced |
|
||||
| Nikto | OSS | Web server scanning |
|
||||
| Nuclei | OSS | Template-based scanning |
|
||||
| Arachni | OSS | Comprehensive scanning |
|
||||
|
||||
## OWASP ZAP
|
||||
|
||||
### Docker Setup
|
||||
|
||||
```bash
|
||||
# Run ZAP in daemon mode
|
||||
docker run -d --name zap \
|
||||
-p 8080:8080 \
|
||||
-v $(pwd)/reports:/zap/reports \
|
||||
ghcr.io/zaproxy/zaproxy:stable \
|
||||
zap.sh -daemon -host 0.0.0.0 -port 8080 \
|
||||
-config api.addrs.addr.name=.* \
|
||||
-config api.addrs.addr.regex=true
|
||||
```
|
||||
|
||||
### Baseline Scan
|
||||
|
||||
```bash
|
||||
# Quick baseline scan
|
||||
docker run --rm -v $(pwd):/zap/wrk \
|
||||
ghcr.io/zaproxy/zaproxy:stable \
|
||||
zap-baseline.py -t https://target.example.com \
|
||||
-r baseline-report.html
|
||||
|
||||
# With authentication
|
||||
docker run --rm -v $(pwd):/zap/wrk \
|
||||
ghcr.io/zaproxy/zaproxy:stable \
|
||||
zap-baseline.py -t https://target.example.com \
|
||||
-r report.html \
|
||||
--auth-login-url https://target.example.com/login \
|
||||
--auth-username user \
|
||||
--auth-password pass
|
||||
```
|
||||
|
||||
### Full Scan
|
||||
|
||||
```bash
|
||||
# Comprehensive scan
|
||||
docker run --rm -v $(pwd):/zap/wrk \
|
||||
ghcr.io/zaproxy/zaproxy:stable \
|
||||
zap-full-scan.py -t https://target.example.com \
|
||||
-r full-report.html \
|
||||
-J full-report.json
|
||||
```
|
||||
|
||||
### API Scan
|
||||
|
||||
```bash
|
||||
# OpenAPI specification scan
|
||||
docker run --rm -v $(pwd):/zap/wrk \
|
||||
ghcr.io/zaproxy/zaproxy:stable \
|
||||
zap-api-scan.py -t https://target.example.com/openapi.json \
|
||||
-f openapi \
|
||||
-r api-report.html
|
||||
```
|
||||
|
||||
### ZAP Automation Framework
|
||||
|
||||
```yaml
|
||||
# zap-automation.yaml
|
||||
env:
|
||||
contexts:
|
||||
- name: "Default Context"
|
||||
urls:
|
||||
- "https://target.example.com"
|
||||
includePaths:
|
||||
- "https://target.example.com/.*"
|
||||
excludePaths:
|
||||
- "https://target.example.com/logout.*"
|
||||
authentication:
|
||||
method: "form"
|
||||
parameters:
|
||||
loginUrl: "https://target.example.com/login"
|
||||
loginRequestData: "username={%username%}&password={%password%}"
|
||||
verification:
|
||||
method: "response"
|
||||
loggedInRegex: "\\QWelcome\\E"
|
||||
users:
|
||||
- name: "testuser"
|
||||
credentials:
|
||||
username: "test@example.com"
|
||||
password: "password123"
|
||||
|
||||
jobs:
|
||||
- type: spider
|
||||
parameters:
|
||||
context: "Default Context"
|
||||
user: "testuser"
|
||||
maxDuration: 10
|
||||
|
||||
- type: spiderAjax
|
||||
parameters:
|
||||
context: "Default Context"
|
||||
user: "testuser"
|
||||
maxDuration: 10
|
||||
|
||||
- type: passiveScan-wait
|
||||
parameters:
|
||||
maxDuration: 5
|
||||
|
||||
- type: activeScan
|
||||
parameters:
|
||||
context: "Default Context"
|
||||
user: "testuser"
|
||||
policy: "Default Policy"
|
||||
|
||||
- type: report
|
||||
parameters:
|
||||
template: "traditional-html"
|
||||
reportDir: "/zap/reports"
|
||||
reportFile: "zap-report"
|
||||
```
|
||||
|
||||
```bash
|
||||
# Run automation
|
||||
docker run --rm -v $(pwd):/zap/wrk \
|
||||
ghcr.io/zaproxy/zaproxy:stable \
|
||||
zap.sh -cmd -autorun /zap/wrk/zap-automation.yaml
|
||||
```
|
||||
|
||||
## CI/CD Integration
|
||||
|
||||
### GitHub Actions
|
||||
|
||||
```yaml
|
||||
name: DAST Scan
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 2 * * *'
|
||||
|
||||
jobs:
|
||||
dast:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Start Application
|
||||
run: |
|
||||
docker-compose up -d
|
||||
sleep 30 # Wait for app to be ready
|
||||
|
||||
- name: OWASP ZAP Scan
|
||||
uses: zaproxy/action-full-scan@v0.8.0
|
||||
with:
|
||||
target: 'http://localhost:8080'
|
||||
rules_file_name: '.zap/rules.tsv'
|
||||
cmd_options: '-a'
|
||||
|
||||
- name: Upload Report
|
||||
uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: zap-report
|
||||
path: report_html.html
|
||||
```
|
||||
|
||||
### GitLab CI
|
||||
|
||||
```yaml
|
||||
dast:
|
||||
stage: security
|
||||
image: ghcr.io/zaproxy/zaproxy:stable
|
||||
variables:
|
||||
TARGET_URL: $DAST_TARGET_URL
|
||||
script:
|
||||
- mkdir -p /zap/wrk/reports
|
||||
- zap-baseline.py -t $TARGET_URL -r /zap/wrk/reports/zap-report.html -I
|
||||
artifacts:
|
||||
paths:
|
||||
- reports/
|
||||
expire_in: 1 week
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH == "main"
|
||||
```
|
||||
|
||||
## Burp Suite Automation
|
||||
|
||||
### REST API Usage
|
||||
|
||||
```python
|
||||
import requests
|
||||
|
||||
class BurpScanner:
|
||||
def __init__(self, api_url, api_key):
|
||||
self.api_url = api_url
|
||||
self.headers = {'Authorization': api_key}
|
||||
|
||||
def create_scan(self, target_url):
|
||||
"""Create and start a new scan."""
|
||||
payload = {
|
||||
'scan_configurations': [
|
||||
{'name': 'Crawl and Audit - Balanced'}
|
||||
],
|
||||
'scope': {
|
||||
'include': [{'rule': target_url}]
|
||||
},
|
||||
'urls': [target_url]
|
||||
}
|
||||
response = requests.post(
|
||||
f'{self.api_url}/v0.1/scan',
|
||||
json=payload,
|
||||
headers=self.headers
|
||||
)
|
||||
return response.headers.get('Location')
|
||||
|
||||
def get_scan_status(self, scan_id):
|
||||
"""Get scan status."""
|
||||
response = requests.get(
|
||||
f'{self.api_url}/v0.1/scan/{scan_id}',
|
||||
headers=self.headers
|
||||
)
|
||||
return response.json()
|
||||
|
||||
def get_issues(self, scan_id):
|
||||
"""Get scan issues."""
|
||||
response = requests.get(
|
||||
f'{self.api_url}/v0.1/scan/{scan_id}/issues',
|
||||
headers=self.headers
|
||||
)
|
||||
return response.json()
|
||||
|
||||
# Usage
|
||||
scanner = BurpScanner('http://burp:1337', 'api-key')
|
||||
scan_id = scanner.create_scan('https://target.example.com')
|
||||
|
||||
while True:
|
||||
status = scanner.get_scan_status(scan_id)
|
||||
if status['scan_status'] == 'succeeded':
|
||||
break
|
||||
time.sleep(30)
|
||||
|
||||
issues = scanner.get_issues(scan_id)
|
||||
```
|
||||
|
||||
## Nikto
|
||||
|
||||
### Basic Scanning
|
||||
|
||||
```bash
|
||||
# Install
|
||||
apt-get install nikto
|
||||
|
||||
# Basic scan
|
||||
nikto -h https://target.example.com
|
||||
|
||||
# With specific options
|
||||
nikto -h https://target.example.com \
|
||||
-ssl \
|
||||
-Tuning 123bde \
|
||||
-output nikto-report.html \
|
||||
-Format html
|
||||
|
||||
# Scan specific ports
|
||||
nikto -h target.example.com -p 80,443,8080
|
||||
```
|
||||
|
||||
## Common DAST Findings
|
||||
|
||||
### OWASP Top 10
|
||||
|
||||
```yaml
|
||||
owasp_findings:
|
||||
A01_Broken_Access_Control:
|
||||
- IDOR vulnerabilities
|
||||
- Missing function-level access control
|
||||
- Privilege escalation
|
||||
|
||||
A02_Cryptographic_Failures:
|
||||
- Sensitive data in URLs
|
||||
- Missing HTTPS
|
||||
- Weak ciphers
|
||||
|
||||
A03_Injection:
|
||||
- SQL injection
|
||||
- Command injection
|
||||
- XSS
|
||||
|
||||
A05_Security_Misconfiguration:
|
||||
- Default credentials
|
||||
- Verbose error messages
|
||||
- Missing security headers
|
||||
|
||||
A07_Auth_Failures:
|
||||
- Weak passwords accepted
|
||||
- Session fixation
|
||||
- Missing MFA
|
||||
```
|
||||
|
||||
## Security Headers Check
|
||||
|
||||
```bash
|
||||
# Check security headers
|
||||
curl -I https://target.example.com | grep -i "x-\|content-security\|strict"
|
||||
|
||||
# Expected headers:
|
||||
# X-Content-Type-Options: nosniff
|
||||
# X-Frame-Options: DENY
|
||||
# X-XSS-Protection: 1; mode=block
|
||||
# Content-Security-Policy: default-src 'self'
|
||||
# Strict-Transport-Security: max-age=31536000
|
||||
```
|
||||
|
||||
## Custom Test Cases
|
||||
|
||||
```yaml
|
||||
# Test authentication
|
||||
tests:
|
||||
- name: "Authentication Bypass"
|
||||
steps:
|
||||
- Access protected resource without auth
|
||||
- Verify 401/403 response
|
||||
- Access with valid auth
|
||||
- Verify 200 response
|
||||
|
||||
- name: "Session Management"
|
||||
steps:
|
||||
- Login and capture session token
|
||||
- Logout
|
||||
- Attempt to use old session
|
||||
- Verify session invalidated
|
||||
|
||||
- name: "Input Validation"
|
||||
steps:
|
||||
- Submit XSS payload in all inputs
|
||||
- Submit SQL injection in all inputs
|
||||
- Verify proper sanitization
|
||||
```
|
||||
|
||||
## Common Issues
|
||||
|
||||
### Issue: False Positives
|
||||
**Problem**: Scanner reports non-vulnerabilities
|
||||
**Solution**: Configure scan policy, review findings manually
|
||||
|
||||
### Issue: Missing Authentication
|
||||
**Problem**: Cannot scan authenticated areas
|
||||
**Solution**: Configure authentication context, use session tokens
|
||||
|
||||
### Issue: Incomplete Coverage
|
||||
**Problem**: Scanner misses endpoints
|
||||
**Solution**: Import API specs, improve spidering, use authenticated scanning
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Test in staging environment first
|
||||
- Configure proper authentication
|
||||
- Import API specifications for complete coverage
|
||||
- Review findings before reporting
|
||||
- Combine with manual testing
|
||||
- Run regular scans (weekly minimum)
|
||||
- Track findings over time
|
||||
- Coordinate with development team
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [sast-scanning](../sast-scanning/) - Static analysis
|
||||
- [penetration-testing](../../operations/penetration-testing/) - Manual testing
|
||||
- [waf-setup](../../network/waf-setup/) - WAF configuration
|
||||
@@ -0,0 +1,105 @@
|
||||
# DAST Tools Reference
|
||||
|
||||
## Tool Comparison
|
||||
|
||||
| Tool | Type | License | Best For |
|
||||
|------|------|---------|----------|
|
||||
| **OWASP ZAP** | Proxy/Scanner | Apache 2.0 | General DAST |
|
||||
| **Nuclei** | Template-based | MIT | Vulnerability checks |
|
||||
| **Nikto** | Web scanner | GPL | Quick scans |
|
||||
| **Burp Suite** | Proxy/Scanner | Commercial | Manual testing |
|
||||
|
||||
## OWASP ZAP
|
||||
|
||||
### CLI Scanning
|
||||
```bash
|
||||
# Quick scan
|
||||
docker run -t owasp/zap2docker-stable zap-baseline.py -t https://target.com
|
||||
|
||||
# Full scan
|
||||
docker run -t owasp/zap2docker-stable zap-full-scan.py -t https://target.com
|
||||
|
||||
# API scan
|
||||
docker run -t owasp/zap2docker-stable zap-api-scan.py \
|
||||
-t https://target.com/openapi.json -f openapi
|
||||
```
|
||||
|
||||
### Automation Framework
|
||||
```yaml
|
||||
# zap-config.yaml
|
||||
env:
|
||||
contexts:
|
||||
- name: "Default Context"
|
||||
urls: ["https://target.com"]
|
||||
authentication:
|
||||
method: "form"
|
||||
parameters:
|
||||
loginUrl: "https://target.com/login"
|
||||
loginRequestData: "user={%username%}&pass={%password%}"
|
||||
jobs:
|
||||
- type: spider
|
||||
parameters:
|
||||
maxDuration: 5
|
||||
- type: activeScan
|
||||
parameters:
|
||||
maxScanDurationInMins: 60
|
||||
- type: report
|
||||
parameters:
|
||||
template: "traditional-html"
|
||||
reportFile: "zap-report.html"
|
||||
```
|
||||
|
||||
## Nuclei
|
||||
|
||||
```bash
|
||||
# Install
|
||||
go install github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest
|
||||
|
||||
# Scan with all templates
|
||||
nuclei -u https://target.com
|
||||
|
||||
# Specific templates
|
||||
nuclei -u https://target.com -t cves/
|
||||
nuclei -u https://target.com -t exposures/
|
||||
|
||||
# Critical and high only
|
||||
nuclei -u https://target.com -severity critical,high
|
||||
|
||||
# Output
|
||||
nuclei -u https://target.com -json -o results.json
|
||||
```
|
||||
|
||||
### Custom Template
|
||||
```yaml
|
||||
id: custom-check
|
||||
info:
|
||||
name: Custom Security Check
|
||||
severity: high
|
||||
requests:
|
||||
- method: GET
|
||||
path:
|
||||
- "{{BaseURL}}/admin"
|
||||
matchers:
|
||||
- type: status
|
||||
status:
|
||||
- 200
|
||||
```
|
||||
|
||||
## CI Integration
|
||||
|
||||
```yaml
|
||||
# GitHub Actions
|
||||
- name: OWASP ZAP Scan
|
||||
uses: zaproxy/action-baseline@v0.9.0
|
||||
with:
|
||||
target: 'https://target.com'
|
||||
rules_file_name: '.zap/rules.tsv'
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. Run in staging, not production
|
||||
2. Use authentication for full coverage
|
||||
3. Exclude logout/destructive endpoints
|
||||
4. Set reasonable timeouts
|
||||
5. Review and triage findings
|
||||
@@ -0,0 +1,432 @@
|
||||
---
|
||||
name: dependency-scanning
|
||||
description: Scan package dependencies for known vulnerabilities using Snyk, Dependabot, and OWASP Dependency-Check. Identify and remediate vulnerable libraries in your software supply chain. Use when managing third-party dependencies or implementing software composition analysis.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# Dependency Scanning
|
||||
|
||||
Identify vulnerabilities in third-party dependencies and libraries.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when:
|
||||
- Managing third-party dependencies
|
||||
- Implementing software composition analysis
|
||||
- Meeting compliance requirements
|
||||
- Securing the software supply chain
|
||||
- Automating vulnerability detection
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Package manifest files (package.json, requirements.txt, etc.)
|
||||
- CI/CD pipeline access
|
||||
- Dependency scanning tool
|
||||
|
||||
## Tool Comparison
|
||||
|
||||
| Tool | Type | Languages | Best For |
|
||||
|------|------|-----------|----------|
|
||||
| Snyk | Commercial/Free | Many | Comprehensive SCA |
|
||||
| Dependabot | Free (GitHub) | Many | Automated PRs |
|
||||
| OWASP Dep-Check | OSS | Many | Free scanning |
|
||||
| npm audit | Built-in | Node.js | Quick checks |
|
||||
| pip-audit | OSS | Python | Python projects |
|
||||
| Trivy | OSS | Many | Container deps |
|
||||
|
||||
## Snyk
|
||||
|
||||
### CLI Usage
|
||||
|
||||
```bash
|
||||
# Install
|
||||
npm install -g snyk
|
||||
|
||||
# Authenticate
|
||||
snyk auth
|
||||
|
||||
# Test project
|
||||
snyk test
|
||||
|
||||
# Monitor project (track over time)
|
||||
snyk monitor
|
||||
|
||||
# Test specific manifest
|
||||
snyk test --file=package.json
|
||||
snyk test --file=requirements.txt
|
||||
|
||||
# Output formats
|
||||
snyk test --json > snyk-results.json
|
||||
snyk test --sarif > snyk-results.sarif
|
||||
|
||||
# Fix vulnerabilities
|
||||
snyk fix
|
||||
|
||||
# Ignore vulnerability
|
||||
snyk ignore --id=SNYK-JS-LODASH-567746 --expiry=2024-12-31 --reason="No exploit path"
|
||||
```
|
||||
|
||||
### CI Integration
|
||||
|
||||
```yaml
|
||||
# .github/workflows/snyk.yml
|
||||
name: Snyk Security
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
snyk:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Run Snyk to check for vulnerabilities
|
||||
uses: snyk/actions/node@master
|
||||
env:
|
||||
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
||||
with:
|
||||
args: --severity-threshold=high
|
||||
|
||||
- name: Upload results to GitHub
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
with:
|
||||
sarif_file: snyk.sarif
|
||||
```
|
||||
|
||||
### Policy File
|
||||
|
||||
```yaml
|
||||
# .snyk
|
||||
version: v1.25.0
|
||||
ignore:
|
||||
SNYK-JS-LODASH-567746:
|
||||
- '*':
|
||||
reason: No user input reaches this function
|
||||
expires: 2024-12-31
|
||||
created: 2024-01-15
|
||||
|
||||
'snyk:lic:npm:gpl-3.0':
|
||||
- '*':
|
||||
reason: Internal use only
|
||||
|
||||
patch: {}
|
||||
```
|
||||
|
||||
## GitHub Dependabot
|
||||
|
||||
### Configuration
|
||||
|
||||
```yaml
|
||||
# .github/dependabot.yml
|
||||
version: 2
|
||||
updates:
|
||||
# JavaScript/Node.js
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
day: "monday"
|
||||
open-pull-requests-limit: 10
|
||||
reviewers:
|
||||
- "security-team"
|
||||
labels:
|
||||
- "dependencies"
|
||||
- "security"
|
||||
ignore:
|
||||
- dependency-name: "aws-sdk"
|
||||
update-types: ["version-update:semver-major"]
|
||||
groups:
|
||||
development-dependencies:
|
||||
dependency-type: "development"
|
||||
update-types:
|
||||
- "minor"
|
||||
- "patch"
|
||||
|
||||
# Python
|
||||
- package-ecosystem: "pip"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
|
||||
# Docker
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
|
||||
# GitHub Actions
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
```
|
||||
|
||||
### Security Alerts
|
||||
|
||||
```yaml
|
||||
# Automated security updates
|
||||
# Enable in repository Settings > Security > Dependabot
|
||||
|
||||
# Dependabot will automatically:
|
||||
# - Create PRs for vulnerable dependencies
|
||||
# - Update to patched versions
|
||||
# - Provide CVE details in PR description
|
||||
```
|
||||
|
||||
## OWASP Dependency-Check
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
# Download
|
||||
wget https://github.com/jeremylong/DependencyCheck/releases/download/v9.0.0/dependency-check-9.0.0-release.zip
|
||||
unzip dependency-check-9.0.0-release.zip
|
||||
|
||||
# Or via Homebrew
|
||||
brew install dependency-check
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
# Scan project
|
||||
dependency-check --project "MyProject" \
|
||||
--scan /path/to/project \
|
||||
--out /path/to/reports \
|
||||
--format HTML \
|
||||
--format JSON
|
||||
|
||||
# With specific analyzers
|
||||
dependency-check --project "MyProject" \
|
||||
--scan . \
|
||||
--enableExperimental \
|
||||
--disableRetireJS
|
||||
|
||||
# CI configuration
|
||||
dependency-check --project "MyProject" \
|
||||
--scan . \
|
||||
--format JSON \
|
||||
--failOnCVSS 7 \
|
||||
--suppression suppression.xml
|
||||
```
|
||||
|
||||
### Suppression File
|
||||
|
||||
```xml
|
||||
<!-- suppression.xml -->
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<suppressions xmlns="https://jeremylong.github.io/DependencyCheck/dependency-suppression.1.3.xsd">
|
||||
<suppress>
|
||||
<notes>False positive - not using vulnerable function</notes>
|
||||
<packageUrl regex="true">^pkg:npm/lodash@.*$</packageUrl>
|
||||
<cve>CVE-2021-23337</cve>
|
||||
</suppress>
|
||||
|
||||
<suppress until="2024-12-31">
|
||||
<notes>Risk accepted - mitigated by WAF</notes>
|
||||
<cpe>cpe:/a:apache:struts:2.5.0</cpe>
|
||||
<vulnerabilityName>CVE-2023-12345</vulnerabilityName>
|
||||
</suppress>
|
||||
</suppressions>
|
||||
```
|
||||
|
||||
### Maven Integration
|
||||
|
||||
```xml
|
||||
<!-- pom.xml -->
|
||||
<plugin>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-maven</artifactId>
|
||||
<version>9.0.0</version>
|
||||
<configuration>
|
||||
<failBuildOnCVSS>7</failBuildOnCVSS>
|
||||
<suppressionFiles>
|
||||
<suppressionFile>suppression.xml</suppressionFile>
|
||||
</suppressionFiles>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
```
|
||||
|
||||
## Language-Specific Tools
|
||||
|
||||
### Node.js (npm audit)
|
||||
|
||||
```bash
|
||||
# Run audit
|
||||
npm audit
|
||||
|
||||
# JSON output
|
||||
npm audit --json
|
||||
|
||||
# Fix automatically
|
||||
npm audit fix
|
||||
|
||||
# Fix with breaking changes
|
||||
npm audit fix --force
|
||||
|
||||
# Production only
|
||||
npm audit --production
|
||||
```
|
||||
|
||||
### Python (pip-audit)
|
||||
|
||||
```bash
|
||||
# Install
|
||||
pip install pip-audit
|
||||
|
||||
# Scan installed packages
|
||||
pip-audit
|
||||
|
||||
# Scan requirements file
|
||||
pip-audit -r requirements.txt
|
||||
|
||||
# Output formats
|
||||
pip-audit --format json
|
||||
pip-audit --format cyclonedx-json
|
||||
|
||||
# Fix vulnerabilities
|
||||
pip-audit --fix
|
||||
```
|
||||
|
||||
### Go (govulncheck)
|
||||
|
||||
```bash
|
||||
# Install
|
||||
go install golang.org/x/vuln/cmd/govulncheck@latest
|
||||
|
||||
# Scan project
|
||||
govulncheck ./...
|
||||
|
||||
# JSON output
|
||||
govulncheck -json ./...
|
||||
```
|
||||
|
||||
### Ruby (bundler-audit)
|
||||
|
||||
```bash
|
||||
# Install
|
||||
gem install bundler-audit
|
||||
|
||||
# Update database
|
||||
bundle-audit update
|
||||
|
||||
# Run audit
|
||||
bundle-audit check
|
||||
|
||||
# Output format
|
||||
bundle-audit check --format json
|
||||
```
|
||||
|
||||
## SBOM Generation
|
||||
|
||||
### CycloneDX
|
||||
|
||||
```bash
|
||||
# Node.js
|
||||
npx @cyclonedx/cyclonedx-npm --output-file sbom.json
|
||||
|
||||
# Python
|
||||
pip install cyclonedx-bom
|
||||
cyclonedx-py -o sbom.json
|
||||
|
||||
# Go
|
||||
go install github.com/CycloneDX/cyclonedx-gomod/cmd/cyclonedx-gomod@latest
|
||||
cyclonedx-gomod mod -json > sbom.json
|
||||
```
|
||||
|
||||
### Syft
|
||||
|
||||
```bash
|
||||
# Install
|
||||
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s
|
||||
|
||||
# Generate SBOM
|
||||
syft dir:/path/to/project -o cyclonedx-json > sbom.json
|
||||
syft dir:/path/to/project -o spdx-json > sbom-spdx.json
|
||||
|
||||
# From container
|
||||
syft myimage:latest -o cyclonedx-json > sbom.json
|
||||
```
|
||||
|
||||
## CI/CD Pipeline
|
||||
|
||||
```yaml
|
||||
# Comprehensive dependency scanning
|
||||
name: Dependency Security
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: '0 8 * * *'
|
||||
|
||||
jobs:
|
||||
scan:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: npm audit
|
||||
run: npm audit --audit-level=high
|
||||
|
||||
- name: Snyk scan
|
||||
uses: snyk/actions/node@master
|
||||
env:
|
||||
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
||||
with:
|
||||
args: --severity-threshold=high
|
||||
|
||||
- name: Generate SBOM
|
||||
run: npx @cyclonedx/cyclonedx-npm --output-file sbom.json
|
||||
|
||||
- name: Upload SBOM
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: sbom
|
||||
path: sbom.json
|
||||
```
|
||||
|
||||
## Common Issues
|
||||
|
||||
### Issue: Too Many Alerts
|
||||
**Problem**: Overwhelmed by vulnerability count
|
||||
**Solution**: Prioritize by exploitability, filter by severity
|
||||
|
||||
### Issue: No Fix Available
|
||||
**Problem**: Vulnerable dependency has no patch
|
||||
**Solution**: Consider alternatives, implement compensating controls
|
||||
|
||||
### Issue: Breaking Updates
|
||||
**Problem**: Security fix breaks functionality
|
||||
**Solution**: Review changelogs, test thoroughly, use lockfiles
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Scan on every build
|
||||
- Use lockfiles for reproducibility
|
||||
- Set severity thresholds
|
||||
- Generate and track SBOMs
|
||||
- Document exceptions properly
|
||||
- Update dependencies regularly
|
||||
- Monitor for new vulnerabilities
|
||||
- Automate PR creation for updates
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [sast-scanning](../sast-scanning/) - Code vulnerabilities
|
||||
- [container-scanning](../container-scanning/) - Container dependencies
|
||||
- [github-actions](../../../devops/ci-cd/github-actions/) - CI integration
|
||||
@@ -0,0 +1,419 @@
|
||||
---
|
||||
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
|
||||
@@ -0,0 +1,106 @@
|
||||
# SAST Tools Reference
|
||||
|
||||
## Tool Comparison
|
||||
|
||||
| Tool | Languages | License | CI Integration |
|
||||
|------|-----------|---------|----------------|
|
||||
| **Semgrep** | 30+ | LGPL/Commercial | Excellent |
|
||||
| **SonarQube** | 30+ | LGPL/Commercial | Excellent |
|
||||
| **CodeQL** | 10+ | MIT | GitHub native |
|
||||
| **Bandit** | Python | Apache 2.0 | Good |
|
||||
| **ESLint Security** | JavaScript | MIT | Good |
|
||||
| **Brakeman** | Ruby | MIT | Good |
|
||||
|
||||
## Semgrep
|
||||
|
||||
```bash
|
||||
# Install
|
||||
pip install semgrep
|
||||
|
||||
# Scan with default rules
|
||||
semgrep --config auto .
|
||||
|
||||
# Scan with specific ruleset
|
||||
semgrep --config p/owasp-top-ten .
|
||||
semgrep --config p/security-audit .
|
||||
|
||||
# Output JSON
|
||||
semgrep --config auto --json -o results.json .
|
||||
```
|
||||
|
||||
### Custom Rules
|
||||
```yaml
|
||||
rules:
|
||||
- id: sql-injection
|
||||
patterns:
|
||||
- pattern: |
|
||||
$QUERY = "..." + $INPUT + "..."
|
||||
- metavariable-regex:
|
||||
metavariable: $QUERY
|
||||
regex: (?i)(select|insert|update|delete)
|
||||
message: "Potential SQL injection"
|
||||
severity: ERROR
|
||||
languages: [python]
|
||||
```
|
||||
|
||||
## SonarQube
|
||||
|
||||
```bash
|
||||
# Scanner CLI
|
||||
sonar-scanner \
|
||||
-Dsonar.projectKey=myproject \
|
||||
-Dsonar.sources=src \
|
||||
-Dsonar.host.url=http://sonarqube:9000 \
|
||||
-Dsonar.token=$SONAR_TOKEN
|
||||
```
|
||||
|
||||
### Quality Gate
|
||||
```yaml
|
||||
# sonar-project.properties
|
||||
sonar.projectKey=myproject
|
||||
sonar.sources=src
|
||||
sonar.tests=tests
|
||||
sonar.coverage.exclusions=**/test/**
|
||||
sonar.qualitygate.wait=true
|
||||
```
|
||||
|
||||
## CodeQL
|
||||
|
||||
```yaml
|
||||
# .github/workflows/codeql.yml
|
||||
- uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: javascript, python
|
||||
|
||||
- uses: github/codeql-action/analyze@v2
|
||||
```
|
||||
|
||||
## Bandit (Python)
|
||||
|
||||
```bash
|
||||
# Run scan
|
||||
bandit -r ./src -f json -o bandit-report.json
|
||||
|
||||
# With severity filter
|
||||
bandit -r ./src -ll # Medium and above
|
||||
```
|
||||
|
||||
## ESLint Security
|
||||
|
||||
```json
|
||||
// .eslintrc
|
||||
{
|
||||
"plugins": ["security"],
|
||||
"extends": ["plugin:security/recommended"]
|
||||
}
|
||||
```
|
||||
|
||||
## CI Integration
|
||||
|
||||
```yaml
|
||||
# GitHub Actions
|
||||
- name: Run Semgrep
|
||||
uses: returntocorp/semgrep-action@v1
|
||||
with:
|
||||
config: p/security-audit
|
||||
```
|
||||
@@ -0,0 +1,411 @@
|
||||
---
|
||||
name: vulnerability-scanning
|
||||
description: Scan systems and dependencies for CVEs and security vulnerabilities. Use tools like Nessus, OpenVAS, and Qualys to identify and prioritize vulnerabilities. Use when performing security assessments, compliance scanning, or vulnerability management.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# Vulnerability Scanning
|
||||
|
||||
Identify and prioritize security vulnerabilities across infrastructure and applications.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when:
|
||||
- Performing security assessments
|
||||
- Implementing vulnerability management programs
|
||||
- Meeting compliance requirements
|
||||
- Triaging and prioritizing remediation
|
||||
- Scanning infrastructure for known CVEs
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Access to scanning tools
|
||||
- Network access to targets
|
||||
- Appropriate authorization
|
||||
|
||||
## Vulnerability Scanning Tools
|
||||
|
||||
| Tool | Type | Best For |
|
||||
|------|------|----------|
|
||||
| Nessus | Commercial | Enterprise scanning |
|
||||
| OpenVAS | Open Source | Free alternative |
|
||||
| Qualys | Cloud SaaS | Large scale |
|
||||
| Nexpose/InsightVM | Commercial | Asset management |
|
||||
| Nuclei | Open Source | Template-based |
|
||||
|
||||
## OpenVAS Setup
|
||||
|
||||
### Docker Deployment
|
||||
|
||||
```bash
|
||||
# Run OpenVAS container
|
||||
docker run -d --name openvas \
|
||||
-p 443:443 \
|
||||
-v openvas-data:/data \
|
||||
greenbone/openvas-scanner
|
||||
|
||||
# Access web UI at https://localhost
|
||||
# Default credentials: admin/admin
|
||||
```
|
||||
|
||||
### Scanning Commands
|
||||
|
||||
```bash
|
||||
# Create target
|
||||
omp -u admin -w admin --xml='<create_target>
|
||||
<name>Web Servers</name>
|
||||
<hosts>192.168.1.0/24</hosts>
|
||||
</create_target>'
|
||||
|
||||
# Create task
|
||||
omp -u admin -w admin --xml='<create_task>
|
||||
<name>Weekly Scan</name>
|
||||
<target id="target-uuid"/>
|
||||
<config id="daba56c8-73ec-11df-a475-002264764cea"/>
|
||||
</create_task>'
|
||||
|
||||
# Start task
|
||||
omp -u admin -w admin --xml='<start_task task_id="task-uuid"/>'
|
||||
|
||||
# Get results
|
||||
omp -u admin -w admin --xml='<get_results task_id="task-uuid"/>'
|
||||
```
|
||||
|
||||
## Nessus
|
||||
|
||||
### API Usage
|
||||
|
||||
```python
|
||||
import requests
|
||||
|
||||
class NessusScanner:
|
||||
def __init__(self, url, access_key, secret_key):
|
||||
self.url = url
|
||||
self.headers = {
|
||||
'X-ApiKeys': f'accessKey={access_key}; secretKey={secret_key}',
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
def create_scan(self, name, targets, template='basic'):
|
||||
"""Create a new scan."""
|
||||
templates = self.get('/editor/scan/templates')
|
||||
template_uuid = next(
|
||||
t['uuid'] for t in templates['templates']
|
||||
if t['name'] == template
|
||||
)
|
||||
|
||||
payload = {
|
||||
'uuid': template_uuid,
|
||||
'settings': {
|
||||
'name': name,
|
||||
'text_targets': targets,
|
||||
'enabled': True
|
||||
}
|
||||
}
|
||||
return self.post('/scans', payload)
|
||||
|
||||
def launch_scan(self, scan_id):
|
||||
"""Start a scan."""
|
||||
return self.post(f'/scans/{scan_id}/launch')
|
||||
|
||||
def get_results(self, scan_id):
|
||||
"""Get scan results."""
|
||||
return self.get(f'/scans/{scan_id}')
|
||||
|
||||
def export_report(self, scan_id, format='pdf'):
|
||||
"""Export scan report."""
|
||||
payload = {'format': format}
|
||||
response = self.post(f'/scans/{scan_id}/export', payload)
|
||||
file_id = response['file']
|
||||
|
||||
# Wait for export
|
||||
while True:
|
||||
status = self.get(f'/scans/{scan_id}/export/{file_id}/status')
|
||||
if status['status'] == 'ready':
|
||||
break
|
||||
time.sleep(5)
|
||||
|
||||
return self.get(f'/scans/{scan_id}/export/{file_id}/download')
|
||||
|
||||
def get(self, path):
|
||||
response = requests.get(f'{self.url}{path}', headers=self.headers, verify=False)
|
||||
return response.json()
|
||||
|
||||
def post(self, path, data=None):
|
||||
response = requests.post(f'{self.url}{path}', json=data, headers=self.headers, verify=False)
|
||||
return response.json()
|
||||
|
||||
# Usage
|
||||
scanner = NessusScanner('https://nessus:8834', 'access-key', 'secret-key')
|
||||
scan = scanner.create_scan('Weekly Infrastructure Scan', '10.0.0.0/24')
|
||||
scanner.launch_scan(scan['scan']['id'])
|
||||
```
|
||||
|
||||
## Nuclei
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
# Install nuclei
|
||||
go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest
|
||||
|
||||
# Or download binary
|
||||
wget https://github.com/projectdiscovery/nuclei/releases/latest/download/nuclei_linux_amd64.zip
|
||||
unzip nuclei_linux_amd64.zip
|
||||
```
|
||||
|
||||
### Basic Scanning
|
||||
|
||||
```bash
|
||||
# Update templates
|
||||
nuclei -update-templates
|
||||
|
||||
# Scan single target
|
||||
nuclei -u https://example.com
|
||||
|
||||
# Scan multiple targets
|
||||
nuclei -l targets.txt
|
||||
|
||||
# Scan with specific templates
|
||||
nuclei -u https://example.com -t cves/
|
||||
nuclei -u https://example.com -t vulnerabilities/
|
||||
|
||||
# Scan with severity filter
|
||||
nuclei -u https://example.com -s critical,high
|
||||
|
||||
# Output formats
|
||||
nuclei -u https://example.com -o results.txt
|
||||
nuclei -u https://example.com -json -o results.json
|
||||
```
|
||||
|
||||
### Custom Templates
|
||||
|
||||
```yaml
|
||||
# custom-check.yaml
|
||||
id: custom-admin-panel
|
||||
|
||||
info:
|
||||
name: Admin Panel Detection
|
||||
author: security-team
|
||||
severity: info
|
||||
tags: recon,panel
|
||||
|
||||
requests:
|
||||
- method: GET
|
||||
path:
|
||||
- "{{BaseURL}}/admin"
|
||||
- "{{BaseURL}}/administrator"
|
||||
- "{{BaseURL}}/wp-admin"
|
||||
|
||||
matchers-condition: or
|
||||
matchers:
|
||||
- type: word
|
||||
words:
|
||||
- "admin"
|
||||
- "login"
|
||||
condition: and
|
||||
|
||||
- type: status
|
||||
status:
|
||||
- 200
|
||||
- 301
|
||||
- 302
|
||||
```
|
||||
|
||||
## CVSS Scoring
|
||||
|
||||
### Severity Levels
|
||||
|
||||
| Score | Rating | Response Time |
|
||||
|-------|--------|---------------|
|
||||
| 9.0-10.0 | Critical | 24 hours |
|
||||
| 7.0-8.9 | High | 7 days |
|
||||
| 4.0-6.9 | Medium | 30 days |
|
||||
| 0.1-3.9 | Low | 90 days |
|
||||
|
||||
### Prioritization Factors
|
||||
|
||||
```yaml
|
||||
prioritization_criteria:
|
||||
critical_factors:
|
||||
- Internet-facing systems
|
||||
- Systems with sensitive data
|
||||
- Active exploitation in the wild
|
||||
- Authentication bypass
|
||||
|
||||
high_factors:
|
||||
- Remote code execution
|
||||
- Privilege escalation
|
||||
- Data exfiltration risk
|
||||
|
||||
context_adjustments:
|
||||
- Compensating controls in place (-1)
|
||||
- No direct exposure (-1)
|
||||
- Critical business system (+1)
|
||||
- Compliance requirement (+1)
|
||||
```
|
||||
|
||||
## Vulnerability Management Process
|
||||
|
||||
### Workflow
|
||||
|
||||
```yaml
|
||||
vulnerability_workflow:
|
||||
discovery:
|
||||
- Run scheduled scans
|
||||
- Import third-party findings
|
||||
- Correlate with asset inventory
|
||||
|
||||
analysis:
|
||||
- Validate findings
|
||||
- Remove false positives
|
||||
- Assess business impact
|
||||
- Prioritize by risk score
|
||||
|
||||
remediation:
|
||||
- Assign to owners
|
||||
- Track SLA compliance
|
||||
- Verify fixes
|
||||
- Document exceptions
|
||||
|
||||
reporting:
|
||||
- Executive summaries
|
||||
- Technical details
|
||||
- Trend analysis
|
||||
- Compliance metrics
|
||||
```
|
||||
|
||||
### Tracking Template
|
||||
|
||||
```markdown
|
||||
## Vulnerability Ticket
|
||||
|
||||
**ID:** VULN-2024-001
|
||||
**CVE:** CVE-2024-12345
|
||||
**CVSS:** 9.8 (Critical)
|
||||
**Affected System:** web-server-01
|
||||
|
||||
### Description
|
||||
Remote code execution vulnerability in Apache Struts.
|
||||
|
||||
### Impact
|
||||
Attacker can execute arbitrary code on the server.
|
||||
|
||||
### Remediation
|
||||
1. Update Apache Struts to version 2.5.33
|
||||
2. Apply WAF rule as temporary mitigation
|
||||
|
||||
### Timeline
|
||||
- Discovered: 2024-01-15
|
||||
- SLA Due: 2024-01-16
|
||||
- Remediated: 2024-01-15
|
||||
|
||||
### Evidence
|
||||
- Scan report: [link]
|
||||
- Screenshot: [link]
|
||||
```
|
||||
|
||||
## CI/CD Integration
|
||||
|
||||
### GitHub Actions
|
||||
|
||||
```yaml
|
||||
name: Vulnerability Scan
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 2 * * *'
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
scan:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Run Nuclei
|
||||
uses: projectdiscovery/nuclei-action@main
|
||||
with:
|
||||
target: https://example.com
|
||||
templates: cves/
|
||||
output: nuclei-results.txt
|
||||
|
||||
- name: Check for critical findings
|
||||
run: |
|
||||
if grep -q "critical" nuclei-results.txt; then
|
||||
echo "Critical vulnerabilities found!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Upload results
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: vulnerability-report
|
||||
path: nuclei-results.txt
|
||||
```
|
||||
|
||||
## Compliance Scanning
|
||||
|
||||
### CIS Benchmark Scan
|
||||
|
||||
```bash
|
||||
# Using OpenSCAP
|
||||
oscap xccdf eval \
|
||||
--profile xccdf_org.ssgproject.content_profile_cis \
|
||||
--results results.xml \
|
||||
--report report.html \
|
||||
/usr/share/xml/scap/ssg/content/ssg-ubuntu2204-ds.xml
|
||||
```
|
||||
|
||||
### PCI DSS Scanning
|
||||
|
||||
```yaml
|
||||
pci_scan_requirements:
|
||||
quarterly:
|
||||
- External vulnerability scan (ASV)
|
||||
- Internal vulnerability scan
|
||||
|
||||
after_changes:
|
||||
- Significant infrastructure changes
|
||||
- New system deployments
|
||||
|
||||
passing_criteria:
|
||||
- No vulnerabilities rated 4.0+ (CVSS)
|
||||
- False positives documented
|
||||
- Scan completed within 90 days
|
||||
```
|
||||
|
||||
## Common Issues
|
||||
|
||||
### Issue: False Positives
|
||||
**Problem**: Scanner reports non-existent vulnerabilities
|
||||
**Solution**: Validate manually, tune scanner, maintain exception list
|
||||
|
||||
### Issue: Incomplete Coverage
|
||||
**Problem**: Not all assets scanned
|
||||
**Solution**: Update asset inventory, verify credentials, check network access
|
||||
|
||||
### Issue: Scan Impact
|
||||
**Problem**: Scans affecting production systems
|
||||
**Solution**: Schedule during maintenance windows, use authenticated scans
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Maintain accurate asset inventory
|
||||
- Schedule regular scan cadence
|
||||
- Validate findings before remediation
|
||||
- Track metrics (MTTR, aging)
|
||||
- Integrate with ticketing systems
|
||||
- Document exceptions properly
|
||||
- Use risk-based prioritization
|
||||
- Automate where possible
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [sast-scanning](../sast-scanning/) - Code analysis
|
||||
- [container-scanning](../container-scanning/) - Container security
|
||||
- [cis-benchmarks](../../hardening/cis-benchmarks/) - Compliance benchmarks
|
||||
@@ -0,0 +1,94 @@
|
||||
# GitHub Actions Vulnerability Scanning Workflow
|
||||
# Add to .github/workflows/security-scan.yaml
|
||||
|
||||
name: Security Scan
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, develop]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
schedule:
|
||||
# Run daily at midnight
|
||||
- cron: '0 0 * * *'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
jobs:
|
||||
trivy-scan:
|
||||
name: Trivy Vulnerability Scan
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Run Trivy vulnerability scanner (filesystem)
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
scan-type: 'fs'
|
||||
scan-ref: '.'
|
||||
format: 'sarif'
|
||||
output: 'trivy-fs-results.sarif'
|
||||
severity: 'CRITICAL,HIGH'
|
||||
|
||||
- name: Upload Trivy scan results to GitHub Security tab
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
if: always()
|
||||
with:
|
||||
sarif_file: 'trivy-fs-results.sarif'
|
||||
|
||||
container-scan:
|
||||
name: Container Image Scan
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'push'
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Build image
|
||||
run: docker build -t myapp:${{ github.sha }} .
|
||||
|
||||
- name: Run Trivy vulnerability scanner (image)
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
image-ref: 'myapp:${{ github.sha }}'
|
||||
format: 'sarif'
|
||||
output: 'trivy-image-results.sarif'
|
||||
severity: 'CRITICAL,HIGH'
|
||||
ignore-unfixed: true
|
||||
|
||||
- name: Upload Trivy scan results
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
if: always()
|
||||
with:
|
||||
sarif_file: 'trivy-image-results.sarif'
|
||||
|
||||
dependency-review:
|
||||
name: Dependency Review
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'pull_request'
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Dependency Review
|
||||
uses: actions/dependency-review-action@v3
|
||||
with:
|
||||
fail-on-severity: high
|
||||
deny-licenses: GPL-3.0, AGPL-3.0
|
||||
|
||||
secrets-scan:
|
||||
name: Secret Detection
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Gitleaks scan
|
||||
uses: gitleaks/gitleaks-action@v2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -0,0 +1,70 @@
|
||||
# Trivy Configuration
|
||||
# Place in project root or ~/.trivy.yaml
|
||||
|
||||
# Scan settings
|
||||
scan:
|
||||
# Scanners to use
|
||||
scanners:
|
||||
- vuln
|
||||
- secret
|
||||
- config
|
||||
|
||||
# Severity levels to report
|
||||
severity:
|
||||
- CRITICAL
|
||||
- HIGH
|
||||
- MEDIUM
|
||||
|
||||
# Vulnerability settings
|
||||
vulnerability:
|
||||
# Ignore unfixed vulnerabilities
|
||||
ignore-unfixed: true
|
||||
|
||||
# Vulnerability types
|
||||
type:
|
||||
- os
|
||||
- library
|
||||
|
||||
# Secret scanning settings
|
||||
secret:
|
||||
config: trivy-secret.yaml
|
||||
|
||||
# Misconfiguration settings
|
||||
misconfiguration:
|
||||
# Policy paths (custom OPA policies)
|
||||
policy:
|
||||
- ./policies
|
||||
|
||||
# Cache settings
|
||||
cache:
|
||||
# Cache directory
|
||||
dir: /tmp/trivy-cache
|
||||
|
||||
# Cache TTL in hours
|
||||
ttl: 24h
|
||||
|
||||
# Database settings
|
||||
db:
|
||||
# Repository for vulnerability database
|
||||
repository: ghcr.io/aquasecurity/trivy-db
|
||||
|
||||
# Output settings
|
||||
format: table
|
||||
output: ""
|
||||
|
||||
# Exit code when vulnerabilities found
|
||||
exit-code: 0
|
||||
|
||||
# Ignore specific files
|
||||
skip-files:
|
||||
- "**/*_test.go"
|
||||
- "**/test/**"
|
||||
|
||||
# Ignore specific directories
|
||||
skip-dirs:
|
||||
- node_modules
|
||||
- vendor
|
||||
- .git
|
||||
|
||||
# Custom ignore file
|
||||
ignorefile: .trivyignore.yaml
|
||||
@@ -0,0 +1,135 @@
|
||||
# Vulnerability Remediation Guide
|
||||
|
||||
## Triage Process
|
||||
|
||||
### 1. Assess Impact
|
||||
- Is the vulnerability exploitable in your context?
|
||||
- Is the vulnerable component reachable?
|
||||
- What's the potential business impact?
|
||||
|
||||
### 2. Prioritize
|
||||
```
|
||||
Priority Matrix:
|
||||
Exploitable
|
||||
Yes No
|
||||
Impact High P1-Critical P2-High
|
||||
Medium P2-High P3-Medium
|
||||
Low P3-Medium P4-Low
|
||||
```
|
||||
|
||||
### 3. Remediation Options
|
||||
|
||||
| Option | When to Use |
|
||||
|--------|-------------|
|
||||
| **Upgrade** | Fix available, no breaking changes |
|
||||
| **Patch** | Apply security patch |
|
||||
| **Workaround** | Mitigate until fix available |
|
||||
| **Accept** | Risk accepted with documentation |
|
||||
| **Remove** | Dependency not needed |
|
||||
|
||||
## Common Remediation Steps
|
||||
|
||||
### Container Base Images
|
||||
|
||||
```dockerfile
|
||||
# Before: Vulnerable base
|
||||
FROM ubuntu:20.04
|
||||
|
||||
# After: Updated base
|
||||
FROM ubuntu:22.04
|
||||
|
||||
# Better: Minimal base
|
||||
FROM gcr.io/distroless/base-debian12
|
||||
```
|
||||
|
||||
### JavaScript Dependencies
|
||||
|
||||
```bash
|
||||
# View outdated packages
|
||||
npm outdated
|
||||
|
||||
# Update specific package
|
||||
npm update lodash
|
||||
|
||||
# Update all (careful!)
|
||||
npm update
|
||||
|
||||
# Force resolution
|
||||
npm audit fix --force
|
||||
|
||||
# Check for updates
|
||||
npx npm-check-updates
|
||||
```
|
||||
|
||||
### Python Dependencies
|
||||
|
||||
```bash
|
||||
# Update specific package
|
||||
pip install --upgrade requests
|
||||
|
||||
# Update with constraints
|
||||
pip install 'requests>=2.28.0,<3.0.0'
|
||||
|
||||
# Using pip-tools
|
||||
pip-compile --upgrade requirements.in
|
||||
```
|
||||
|
||||
### Terraform Providers
|
||||
|
||||
```hcl
|
||||
# Pin to secure version
|
||||
terraform {
|
||||
required_providers {
|
||||
aws = {
|
||||
source = "hashicorp/aws"
|
||||
version = "~> 5.0" # Update to latest minor
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## False Positive Handling
|
||||
|
||||
### Trivy Ignore
|
||||
```yaml
|
||||
# .trivyignore
|
||||
CVE-2022-12345 # Reason: Not exploitable in our context
|
||||
CVE-2022-67890 # Reason: Component not exposed
|
||||
```
|
||||
|
||||
### Grype Ignore
|
||||
```yaml
|
||||
# .grype.yaml
|
||||
ignore:
|
||||
- vulnerability: CVE-2022-12345
|
||||
reason: "Not applicable - component not used"
|
||||
```
|
||||
|
||||
## Documentation Template
|
||||
|
||||
```markdown
|
||||
## Vulnerability Assessment: CVE-XXXX-XXXXX
|
||||
|
||||
**Severity:** High (CVSS 7.5)
|
||||
**Component:** package-name v1.2.3
|
||||
**Status:** [Remediated/Accepted/Pending]
|
||||
|
||||
### Description
|
||||
Brief description of the vulnerability.
|
||||
|
||||
### Impact Assessment
|
||||
- Exploitability in our environment: [Yes/No/Partial]
|
||||
- Affected systems: [List systems]
|
||||
- Business impact: [Description]
|
||||
|
||||
### Remediation
|
||||
- Action taken: Upgraded to v1.2.4
|
||||
- Date: YYYY-MM-DD
|
||||
- Verified by: [Name]
|
||||
|
||||
### If Accepted
|
||||
- Reason for acceptance:
|
||||
- Compensating controls:
|
||||
- Review date:
|
||||
- Approved by:
|
||||
```
|
||||
@@ -0,0 +1,93 @@
|
||||
# Vulnerability Scanner Comparison
|
||||
|
||||
## Container Image Scanners
|
||||
|
||||
| Tool | License | Speed | Database | CI Integration |
|
||||
|------|---------|-------|----------|----------------|
|
||||
| **Trivy** | Apache 2.0 | Fast | NVD, Red Hat, etc. | Excellent |
|
||||
| **Grype** | Apache 2.0 | Fast | Anchore DB | Good |
|
||||
| **Clair** | Apache 2.0 | Medium | NVD, Alpine, etc. | Good |
|
||||
| **Snyk** | Commercial | Fast | Snyk DB | Excellent |
|
||||
| **Docker Scout** | Commercial | Fast | Docker DB | Native |
|
||||
|
||||
## Recommended: Trivy
|
||||
|
||||
### Installation
|
||||
```bash
|
||||
# Homebrew
|
||||
brew install trivy
|
||||
|
||||
# APT
|
||||
apt-get install trivy
|
||||
|
||||
# Docker
|
||||
docker run aquasec/trivy image nginx:latest
|
||||
```
|
||||
|
||||
### Basic Usage
|
||||
```bash
|
||||
# Scan image
|
||||
trivy image nginx:latest
|
||||
|
||||
# Scan with severity filter
|
||||
trivy image --severity HIGH,CRITICAL nginx:latest
|
||||
|
||||
# Scan and fail on vulnerabilities
|
||||
trivy image --exit-code 1 --severity CRITICAL nginx:latest
|
||||
|
||||
# JSON output
|
||||
trivy image -f json -o results.json nginx:latest
|
||||
|
||||
# Scan filesystem
|
||||
trivy fs /path/to/project
|
||||
|
||||
# Scan Kubernetes
|
||||
trivy k8s --report summary cluster
|
||||
```
|
||||
|
||||
### GitHub Actions
|
||||
```yaml
|
||||
- name: Run Trivy vulnerability scanner
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
image-ref: 'myapp:${{ github.sha }}'
|
||||
format: 'sarif'
|
||||
output: 'trivy-results.sarif'
|
||||
severity: 'CRITICAL,HIGH'
|
||||
|
||||
- name: Upload Trivy scan results
|
||||
uses: github/codeql-action/upload-sarif@v2
|
||||
with:
|
||||
sarif_file: 'trivy-results.sarif'
|
||||
```
|
||||
|
||||
## Dependency Scanners
|
||||
|
||||
| Tool | Languages | License |
|
||||
|------|-----------|---------|
|
||||
| **npm audit** | JavaScript | Free |
|
||||
| **pip-audit** | Python | Free |
|
||||
| **bundle audit** | Ruby | Free |
|
||||
| **cargo audit** | Rust | Free |
|
||||
| **Snyk** | Multi | Commercial |
|
||||
| **Dependabot** | Multi | Free (GitHub) |
|
||||
| **OWASP Dependency-Check** | Multi | Apache 2.0 |
|
||||
|
||||
## Infrastructure as Code Scanners
|
||||
|
||||
| Tool | Targets | License |
|
||||
|------|---------|---------|
|
||||
| **tfsec** | Terraform | MIT |
|
||||
| **checkov** | TF, CloudFormation, K8s | Apache 2.0 |
|
||||
| **kics** | Multi IaC | Apache 2.0 |
|
||||
| **kubesec** | Kubernetes | Apache 2.0 |
|
||||
|
||||
## CVSS Score Reference
|
||||
|
||||
| Score | Severity |
|
||||
|-------|----------|
|
||||
| 0.0 | None |
|
||||
| 0.1-3.9 | Low |
|
||||
| 4.0-6.9 | Medium |
|
||||
| 7.0-8.9 | High |
|
||||
| 9.0-10.0 | Critical |
|
||||
@@ -0,0 +1,53 @@
|
||||
#!/bin/bash
|
||||
# Container Image Vulnerability Scanner
|
||||
# Usage: ./scan-images.sh <image> [--severity HIGH,CRITICAL] [--format json|table]
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
IMAGE="${1:-}"
|
||||
SEVERITY="${2:-HIGH,CRITICAL}"
|
||||
FORMAT="${3:-table}"
|
||||
|
||||
if [ -z "$IMAGE" ]; then
|
||||
echo "Usage: $0 <image> [--severity HIGH,CRITICAL] [--format json|table]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "========================================="
|
||||
echo "Scanning Image: $IMAGE"
|
||||
echo "Severity Filter: $SEVERITY"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
|
||||
# Check which scanner is available
|
||||
if command -v trivy &>/dev/null; then
|
||||
echo "Using Trivy scanner..."
|
||||
trivy image \
|
||||
--severity "$SEVERITY" \
|
||||
--format "$FORMAT" \
|
||||
--ignore-unfixed \
|
||||
"$IMAGE"
|
||||
|
||||
elif command -v grype &>/dev/null; then
|
||||
echo "Using Grype scanner..."
|
||||
grype "$IMAGE" \
|
||||
--only-fixed \
|
||||
--fail-on high \
|
||||
-o "$FORMAT"
|
||||
|
||||
elif command -v docker &>/dev/null && docker scout version &>/dev/null 2>&1; then
|
||||
echo "Using Docker Scout..."
|
||||
docker scout cves "$IMAGE" \
|
||||
--only-severity critical,high \
|
||||
--format "$FORMAT"
|
||||
|
||||
else
|
||||
echo "Error: No vulnerability scanner found."
|
||||
echo "Install one of: trivy, grype, or docker scout"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "========================================="
|
||||
echo "Scan complete"
|
||||
echo "========================================="
|
||||
@@ -0,0 +1,81 @@
|
||||
#!/bin/bash
|
||||
# Repository Vulnerability Scanner
|
||||
# Scans for vulnerabilities in dependencies and IaC
|
||||
# Usage: ./scan-repo.sh [directory] [--output report.json]
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCAN_DIR="${1:-.}"
|
||||
OUTPUT="${2:-}"
|
||||
|
||||
echo "========================================="
|
||||
echo "Repository Security Scan"
|
||||
echo "Directory: $SCAN_DIR"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
|
||||
ISSUES_FOUND=0
|
||||
|
||||
# Trivy filesystem scan
|
||||
if command -v trivy &>/dev/null; then
|
||||
echo "=== Trivy Filesystem Scan ==="
|
||||
trivy fs "$SCAN_DIR" \
|
||||
--severity HIGH,CRITICAL \
|
||||
--scanners vuln,secret,config \
|
||||
--ignore-unfixed \
|
||||
|| ISSUES_FOUND=1
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Check for secrets with gitleaks
|
||||
if command -v gitleaks &>/dev/null; then
|
||||
echo "=== GitLeaks Secret Scan ==="
|
||||
gitleaks detect --source "$SCAN_DIR" --no-git || ISSUES_FOUND=1
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Check Terraform with tfsec
|
||||
if command -v tfsec &>/dev/null && [ -d "$SCAN_DIR" ]; then
|
||||
if find "$SCAN_DIR" -name "*.tf" -print -quit | grep -q .; then
|
||||
echo "=== TFSec Terraform Scan ==="
|
||||
tfsec "$SCAN_DIR" --minimum-severity HIGH || ISSUES_FOUND=1
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check Kubernetes manifests with kubesec
|
||||
if command -v kubesec &>/dev/null; then
|
||||
for manifest in $(find "$SCAN_DIR" -name "*.yaml" -o -name "*.yml" 2>/dev/null | head -10); do
|
||||
if grep -q "kind:" "$manifest" 2>/dev/null; then
|
||||
echo "=== Kubesec: $manifest ==="
|
||||
kubesec scan "$manifest" 2>/dev/null || true
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Python dependencies
|
||||
if [ -f "$SCAN_DIR/requirements.txt" ]; then
|
||||
if command -v pip-audit &>/dev/null; then
|
||||
echo "=== Python Dependency Audit ==="
|
||||
pip-audit -r "$SCAN_DIR/requirements.txt" || ISSUES_FOUND=1
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
|
||||
# Node.js dependencies
|
||||
if [ -f "$SCAN_DIR/package.json" ]; then
|
||||
if command -v npm &>/dev/null; then
|
||||
echo "=== NPM Audit ==="
|
||||
(cd "$SCAN_DIR" && npm audit --audit-level=high 2>/dev/null) || ISSUES_FOUND=1
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "========================================="
|
||||
if [ $ISSUES_FOUND -eq 1 ]; then
|
||||
echo "⚠ Security issues found - review above"
|
||||
exit 1
|
||||
else
|
||||
echo "✓ No critical security issues found"
|
||||
fi
|
||||
echo "========================================="
|
||||
Reference in New Issue
Block a user