This commit is contained in:
Toby
2026-01-27 17:35:45 -05:00
commit 2639af6531
176 changed files with 27104 additions and 0 deletions
@@ -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
+399
View File
@@ -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
+419
View File
@@ -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 "========================================="