Initial commit
This commit is contained in:
9
skills/appsec/dast-nuclei/assets/.gitkeep
Normal file
9
skills/appsec/dast-nuclei/assets/.gitkeep
Normal file
@@ -0,0 +1,9 @@
|
||||
# Assets Directory
|
||||
|
||||
Place files that will be used in the output Claude produces:
|
||||
- Templates
|
||||
- Configuration files
|
||||
- Images/logos
|
||||
- Boilerplate code
|
||||
|
||||
These files are NOT loaded into context but copied/modified in output.
|
||||
357
skills/appsec/dast-nuclei/assets/ci-config-template.yml
Normal file
357
skills/appsec/dast-nuclei/assets/ci-config-template.yml
Normal file
@@ -0,0 +1,357 @@
|
||||
# Security-Enhanced CI/CD Pipeline Template
|
||||
#
|
||||
# This template demonstrates security best practices for CI/CD pipelines.
|
||||
# Adapt this template to your specific security tool and workflow needs.
|
||||
#
|
||||
# Key Security Features:
|
||||
# - SAST (Static Application Security Testing)
|
||||
# - Dependency vulnerability scanning
|
||||
# - Secrets detection
|
||||
# - Infrastructure-as-Code security scanning
|
||||
# - Container image scanning
|
||||
# - Security artifact uploading for compliance
|
||||
|
||||
name: Security Scan Pipeline
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, develop]
|
||||
pull_request:
|
||||
branches: [main, develop]
|
||||
schedule:
|
||||
# Run weekly security scans on Sunday at 2 AM UTC
|
||||
- cron: '0 2 * * 0'
|
||||
workflow_dispatch: # Allow manual trigger
|
||||
|
||||
# Security: Restrict permissions to minimum required
|
||||
permissions:
|
||||
contents: read
|
||||
security-events: write # For uploading SARIF results
|
||||
pull-requests: write # For commenting on PRs
|
||||
|
||||
env:
|
||||
# Configuration
|
||||
SECURITY_SCAN_FAIL_ON: 'critical,high' # Fail build on these severities
|
||||
REPORT_DIR: 'security-reports'
|
||||
|
||||
jobs:
|
||||
# Job 1: Static Application Security Testing (SAST)
|
||||
sast-scan:
|
||||
name: SAST Security Scan
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # Full history for better analysis
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
|
||||
- name: Run SAST Scanner
|
||||
run: |
|
||||
# Example: Using Semgrep for SAST
|
||||
pip install semgrep
|
||||
semgrep --config=auto \
|
||||
--json \
|
||||
--output ${{ env.REPORT_DIR }}/sast-results.json \
|
||||
. || true
|
||||
|
||||
# Alternative: Bandit for Python projects
|
||||
# pip install bandit
|
||||
# bandit -r . -f json -o ${{ env.REPORT_DIR }}/bandit-results.json
|
||||
|
||||
- name: Process SAST Results
|
||||
run: |
|
||||
# Parse results and fail on critical/high severity
|
||||
python3 -c "
|
||||
import json
|
||||
import sys
|
||||
|
||||
with open('${{ env.REPORT_DIR }}/sast-results.json') as f:
|
||||
results = json.load(f)
|
||||
|
||||
critical = len([r for r in results.get('results', []) if r.get('extra', {}).get('severity') == 'ERROR'])
|
||||
high = len([r for r in results.get('results', []) if r.get('extra', {}).get('severity') == 'WARNING'])
|
||||
|
||||
print(f'Critical findings: {critical}')
|
||||
print(f'High findings: {high}')
|
||||
|
||||
if critical > 0:
|
||||
print('❌ Build failed: Critical security issues found')
|
||||
sys.exit(1)
|
||||
elif high > 0:
|
||||
print('⚠️ Warning: High severity issues found')
|
||||
# Optionally fail on high severity
|
||||
# sys.exit(1)
|
||||
else:
|
||||
print('✅ No critical security issues found')
|
||||
"
|
||||
|
||||
- name: Upload SAST Results
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: sast-results
|
||||
path: ${{ env.REPORT_DIR }}/sast-results.json
|
||||
retention-days: 30
|
||||
|
||||
# Job 2: Dependency Vulnerability Scanning
|
||||
dependency-scan:
|
||||
name: Dependency Vulnerability Scan
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
|
||||
- name: Scan Python Dependencies
|
||||
if: hashFiles('requirements.txt') != ''
|
||||
run: |
|
||||
pip install safety
|
||||
safety check \
|
||||
--json \
|
||||
--output ${{ env.REPORT_DIR }}/safety-results.json \
|
||||
|| true
|
||||
|
||||
- name: Scan Node Dependencies
|
||||
if: hashFiles('package.json') != ''
|
||||
run: |
|
||||
npm audit --json > ${{ env.REPORT_DIR }}/npm-audit.json || true
|
||||
|
||||
- name: Process Dependency Results
|
||||
run: |
|
||||
# Check for critical vulnerabilities
|
||||
if [ -f "${{ env.REPORT_DIR }}/safety-results.json" ]; then
|
||||
critical_count=$(python3 -c "import json; data=json.load(open('${{ env.REPORT_DIR }}/safety-results.json')); print(len([v for v in data.get('vulnerabilities', []) if v.get('severity', '').lower() == 'critical']))")
|
||||
echo "Critical vulnerabilities: $critical_count"
|
||||
if [ "$critical_count" -gt "0" ]; then
|
||||
echo "❌ Build failed: Critical vulnerabilities in dependencies"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
- name: Upload Dependency Scan Results
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: dependency-scan-results
|
||||
path: ${{ env.REPORT_DIR }}/
|
||||
retention-days: 30
|
||||
|
||||
# Job 3: Secrets Detection
|
||||
secrets-scan:
|
||||
name: Secrets Detection
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # Full history to scan all commits
|
||||
|
||||
- name: Run Gitleaks
|
||||
uses: gitleaks/gitleaks-action@v2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITLEAKS_ENABLE_SUMMARY: true
|
||||
|
||||
- name: Alternative - TruffleHog Scan
|
||||
if: false # Set to true to enable
|
||||
run: |
|
||||
pip install truffleHog
|
||||
trufflehog --json --regex --entropy=True . \
|
||||
> ${{ env.REPORT_DIR }}/trufflehog-results.json || true
|
||||
|
||||
- name: Upload Secrets Scan Results
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: secrets-scan-results
|
||||
path: ${{ env.REPORT_DIR }}/
|
||||
retention-days: 30
|
||||
|
||||
# Job 4: Container Image Scanning
|
||||
container-scan:
|
||||
name: Container Image Security Scan
|
||||
runs-on: ubuntu-latest
|
||||
if: hashFiles('Dockerfile') != ''
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Build Docker Image
|
||||
run: |
|
||||
docker build -t app:${{ github.sha }} .
|
||||
|
||||
- name: Run Trivy Scanner
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
image-ref: app:${{ github.sha }}
|
||||
format: 'sarif'
|
||||
output: '${{ env.REPORT_DIR }}/trivy-results.sarif'
|
||||
severity: 'CRITICAL,HIGH'
|
||||
|
||||
- name: Upload Trivy Results to GitHub Security
|
||||
if: always()
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
with:
|
||||
sarif_file: '${{ env.REPORT_DIR }}/trivy-results.sarif'
|
||||
|
||||
- name: Upload Container Scan Results
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: container-scan-results
|
||||
path: ${{ env.REPORT_DIR }}/
|
||||
retention-days: 30
|
||||
|
||||
# Job 5: Infrastructure-as-Code Security Scanning
|
||||
iac-scan:
|
||||
name: IaC Security Scan
|
||||
runs-on: ubuntu-latest
|
||||
if: hashFiles('**/*.tf', '**/*.yaml', '**/*.yml') != ''
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Run Checkov
|
||||
run: |
|
||||
pip install checkov
|
||||
checkov -d . \
|
||||
--output json \
|
||||
--output-file ${{ env.REPORT_DIR }}/checkov-results.json \
|
||||
--quiet \
|
||||
|| true
|
||||
|
||||
- name: Run tfsec (for Terraform)
|
||||
if: hashFiles('**/*.tf') != ''
|
||||
run: |
|
||||
curl -s https://raw.githubusercontent.com/aquasecurity/tfsec/master/scripts/install_linux.sh | bash
|
||||
tfsec . \
|
||||
--format json \
|
||||
--out ${{ env.REPORT_DIR }}/tfsec-results.json \
|
||||
|| true
|
||||
|
||||
- name: Process IaC Results
|
||||
run: |
|
||||
# Fail on critical findings
|
||||
if [ -f "${{ env.REPORT_DIR }}/checkov-results.json" ]; then
|
||||
critical_count=$(python3 -c "import json; data=json.load(open('${{ env.REPORT_DIR }}/checkov-results.json')); print(data.get('summary', {}).get('failed', 0))")
|
||||
echo "Failed checks: $critical_count"
|
||||
if [ "$critical_count" -gt "0" ]; then
|
||||
echo "⚠️ Warning: IaC security issues found"
|
||||
# Optionally fail the build
|
||||
# exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
- name: Upload IaC Scan Results
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: iac-scan-results
|
||||
path: ${{ env.REPORT_DIR }}/
|
||||
retention-days: 30
|
||||
|
||||
# Job 6: Security Report Generation and Notification
|
||||
security-report:
|
||||
name: Generate Security Report
|
||||
runs-on: ubuntu-latest
|
||||
needs: [sast-scan, dependency-scan, secrets-scan]
|
||||
if: always()
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Download All Scan Results
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: all-results/
|
||||
|
||||
- name: Generate Consolidated Report
|
||||
run: |
|
||||
# Consolidate all security scan results
|
||||
mkdir -p consolidated-report
|
||||
|
||||
cat > consolidated-report/security-summary.md << 'EOF'
|
||||
# Security Scan Summary
|
||||
|
||||
**Scan Date**: $(date -u +"%Y-%m-%d %H:%M:%S UTC")
|
||||
**Commit**: ${{ github.sha }}
|
||||
**Branch**: ${{ github.ref_name }}
|
||||
|
||||
## Scan Results
|
||||
|
||||
### SAST Scan
|
||||
See artifacts: `sast-results`
|
||||
|
||||
### Dependency Scan
|
||||
See artifacts: `dependency-scan-results`
|
||||
|
||||
### Secrets Scan
|
||||
See artifacts: `secrets-scan-results`
|
||||
|
||||
### Container Scan
|
||||
See artifacts: `container-scan-results`
|
||||
|
||||
### IaC Scan
|
||||
See artifacts: `iac-scan-results`
|
||||
|
||||
---
|
||||
|
||||
For detailed results, download scan artifacts from this workflow run.
|
||||
EOF
|
||||
|
||||
- name: Comment on PR (if applicable)
|
||||
if: github.event_name == 'pull_request'
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const fs = require('fs');
|
||||
const report = fs.readFileSync('consolidated-report/security-summary.md', 'utf8');
|
||||
|
||||
github.rest.issues.createComment({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: report
|
||||
});
|
||||
|
||||
- name: Upload Consolidated Report
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: consolidated-security-report
|
||||
path: consolidated-report/
|
||||
retention-days: 90
|
||||
|
||||
# Security Best Practices Demonstrated:
|
||||
#
|
||||
# 1. ✅ Minimal permissions (principle of least privilege)
|
||||
# 2. ✅ Multiple security scan types (defense in depth)
|
||||
# 3. ✅ Fail-fast on critical findings
|
||||
# 4. ✅ Secrets detection across full git history
|
||||
# 5. ✅ Container image scanning before deployment
|
||||
# 6. ✅ IaC scanning for misconfigurations
|
||||
# 7. ✅ Artifact retention for compliance audit trail
|
||||
# 8. ✅ SARIF format for GitHub Security integration
|
||||
# 9. ✅ Scheduled scans for continuous monitoring
|
||||
# 10. ✅ PR comments for developer feedback
|
||||
#
|
||||
# Compliance Mappings:
|
||||
# - SOC 2: CC6.1, CC6.6, CC7.2 (Security monitoring and logging)
|
||||
# - PCI-DSS: 6.2, 6.5 (Secure development practices)
|
||||
# - NIST: SA-11 (Developer Security Testing)
|
||||
# - OWASP: Integrated security testing throughout SDLC
|
||||
192
skills/appsec/dast-nuclei/assets/github_actions.yml
Normal file
192
skills/appsec/dast-nuclei/assets/github_actions.yml
Normal file
@@ -0,0 +1,192 @@
|
||||
# GitHub Actions Workflow for Nuclei Security Scanning
|
||||
# Place this file in .github/workflows/nuclei-scan.yml
|
||||
|
||||
name: Nuclei Security Scan
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main, develop ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
schedule:
|
||||
# Run daily at 2 AM UTC
|
||||
- cron: '0 2 * * *'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
target_url:
|
||||
description: 'Target URL to scan'
|
||||
required: true
|
||||
default: 'https://staging.example.com'
|
||||
severity:
|
||||
description: 'Severity levels (comma-separated)'
|
||||
required: false
|
||||
default: 'critical,high'
|
||||
|
||||
env:
|
||||
# Default target URL (override with workflow_dispatch input)
|
||||
TARGET_URL: https://staging.example.com
|
||||
# Severity levels to scan
|
||||
SEVERITY: critical,high
|
||||
# Template tags to use
|
||||
TEMPLATE_TAGS: cve,owasp,misconfig
|
||||
|
||||
jobs:
|
||||
nuclei-scan:
|
||||
name: Nuclei Vulnerability Scan
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.11'
|
||||
|
||||
- name: Run Nuclei Scan
|
||||
id: nuclei
|
||||
uses: projectdiscovery/nuclei-action@main
|
||||
with:
|
||||
target: ${{ github.event.inputs.target_url || env.TARGET_URL }}
|
||||
severity: ${{ github.event.inputs.severity || env.SEVERITY }}
|
||||
templates: ${{ env.TEMPLATE_TAGS }}
|
||||
output: nuclei-results.jsonl
|
||||
|
||||
- name: Parse Nuclei Results
|
||||
if: always()
|
||||
run: |
|
||||
# Install dependencies (if using custom parser)
|
||||
# pip install -r requirements.txt
|
||||
|
||||
# Parse results and generate HTML report
|
||||
if [ -f nuclei-results.jsonl ]; then
|
||||
echo "Parsing Nuclei results..."
|
||||
python3 scripts/parse_nuclei_results.py \
|
||||
--input nuclei-results.jsonl \
|
||||
--output nuclei-report.html \
|
||||
--format html
|
||||
|
||||
# Count findings by severity
|
||||
CRITICAL=$(grep -c '"severity":"critical"' nuclei-results.jsonl || echo 0)
|
||||
HIGH=$(grep -c '"severity":"high"' nuclei-results.jsonl || echo 0)
|
||||
TOTAL=$(wc -l < nuclei-results.jsonl)
|
||||
|
||||
echo "## Nuclei Scan Results" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Total Findings**: $TOTAL" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Critical**: $CRITICAL" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **High**: $HIGH" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
# Set outputs
|
||||
echo "critical=$CRITICAL" >> $GITHUB_OUTPUT
|
||||
echo "high=$HIGH" >> $GITHUB_OUTPUT
|
||||
echo "total=$TOTAL" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "No findings detected" >> $GITHUB_STEP_SUMMARY
|
||||
echo "critical=0" >> $GITHUB_OUTPUT
|
||||
echo "high=0" >> $GITHUB_OUTPUT
|
||||
echo "total=0" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Upload SARIF file
|
||||
if: always()
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
with:
|
||||
sarif_file: nuclei.sarif
|
||||
category: nuclei
|
||||
|
||||
- name: Upload Artifacts
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: nuclei-scan-results
|
||||
path: |
|
||||
nuclei-results.jsonl
|
||||
nuclei-report.html
|
||||
nuclei.sarif
|
||||
retention-days: 30
|
||||
|
||||
- name: Comment on PR
|
||||
if: github.event_name == 'pull_request' && always()
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const critical = '${{ steps.nuclei.outputs.critical || 0 }}';
|
||||
const high = '${{ steps.nuclei.outputs.high || 0 }}';
|
||||
const total = '${{ steps.nuclei.outputs.total || 0 }}';
|
||||
|
||||
const body = `## 🔒 Nuclei Security Scan Results
|
||||
|
||||
| Severity | Count |
|
||||
|----------|-------|
|
||||
| Critical | ${critical} |
|
||||
| High | ${high} |
|
||||
| **Total** | **${total}** |
|
||||
|
||||
${critical > 0 ? '⚠️ **Critical vulnerabilities detected!**' : ''}
|
||||
${high > 0 ? '⚠️ High severity vulnerabilities detected.' : ''}
|
||||
|
||||
View detailed results in the [workflow artifacts](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}).`;
|
||||
|
||||
github.rest.issues.createComment({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: body
|
||||
});
|
||||
|
||||
- name: Fail on Critical Findings
|
||||
if: steps.nuclei.outputs.critical > 0
|
||||
run: |
|
||||
echo "::error::Critical vulnerabilities detected!"
|
||||
exit 1
|
||||
|
||||
- name: Notify on Slack
|
||||
if: failure() && steps.nuclei.outputs.critical > 0
|
||||
uses: slackapi/slack-github-action@v1
|
||||
with:
|
||||
payload: |
|
||||
{
|
||||
"text": "🚨 Critical vulnerabilities detected in ${{ github.repository }}",
|
||||
"blocks": [
|
||||
{
|
||||
"type": "section",
|
||||
"text": {
|
||||
"type": "mrkdwn",
|
||||
"text": "*Critical Security Vulnerabilities Detected*\n\n*Repository:* ${{ github.repository }}\n*Branch:* ${{ github.ref_name }}\n*Critical Findings:* ${{ steps.nuclei.outputs.critical }}\n*High Findings:* ${{ steps.nuclei.outputs.high }}\n\n<https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Scan Results>"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||
|
||||
# Optional: Separate job for authenticated scanning
|
||||
nuclei-authenticated-scan:
|
||||
name: Nuclei Authenticated Scan
|
||||
runs-on: ubuntu-latest
|
||||
if: github.ref == 'refs/heads/main' # Only run on main branch
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Run Authenticated Scan
|
||||
uses: projectdiscovery/nuclei-action@main
|
||||
with:
|
||||
target: ${{ env.TARGET_URL }}
|
||||
severity: critical,high
|
||||
templates: cve,owasp
|
||||
# Add authentication headers from secrets
|
||||
headers: |
|
||||
Authorization: Bearer ${{ secrets.API_TOKEN }}
|
||||
Cookie: session=${{ secrets.SESSION_COOKIE }}
|
||||
output: nuclei-auth-results.jsonl
|
||||
|
||||
- name: Upload Authenticated Results
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: nuclei-authenticated-scan-results
|
||||
path: nuclei-auth-results.jsonl
|
||||
retention-days: 30
|
||||
225
skills/appsec/dast-nuclei/assets/nuclei_config.yaml
Normal file
225
skills/appsec/dast-nuclei/assets/nuclei_config.yaml
Normal file
@@ -0,0 +1,225 @@
|
||||
# Nuclei Configuration File
|
||||
# Save as ~/.config/nuclei/config.yaml or specify with -config flag
|
||||
|
||||
# Template configuration
|
||||
templates:
|
||||
# Auto-update templates on each run
|
||||
update-templates: true
|
||||
|
||||
# Template directory (default: ~/.nuclei-templates/)
|
||||
# templates-directory: /custom/path/to/templates
|
||||
|
||||
# Custom template paths
|
||||
# custom-templates:
|
||||
# - /path/to/custom/templates/
|
||||
# - /path/to/organization/templates/
|
||||
|
||||
# Scan configuration
|
||||
severity:
|
||||
- critical
|
||||
- high
|
||||
# - medium
|
||||
# - low
|
||||
# - info
|
||||
|
||||
# Rate limiting (requests per second)
|
||||
rate-limit: 50
|
||||
|
||||
# Concurrency (parallel template execution)
|
||||
concurrency: 10
|
||||
|
||||
# Bulk size (parallel host scanning)
|
||||
bulk-size: 10
|
||||
|
||||
# Timeout per request (seconds)
|
||||
timeout: 10
|
||||
|
||||
# Retries for failed requests
|
||||
retries: 1
|
||||
|
||||
# HTTP configuration
|
||||
http:
|
||||
# User agent
|
||||
user-agent: "Mozilla/5.0 (compatible; Nuclei/3.0)"
|
||||
|
||||
# Follow redirects
|
||||
follow-redirects: true
|
||||
|
||||
# Max redirects to follow
|
||||
max-redirects: 3
|
||||
|
||||
# Custom headers (applied to all requests)
|
||||
# headers:
|
||||
# - "X-Custom-Header: value"
|
||||
# - "Authorization: Bearer token"
|
||||
|
||||
# Proxy configuration
|
||||
# proxy: http://proxy.example.com:8080
|
||||
# proxy-socks: socks5://proxy.example.com:1080
|
||||
|
||||
# Network configuration
|
||||
network:
|
||||
# Disable SSL/TLS verification (use with caution)
|
||||
# disable-ssl-verification: false
|
||||
|
||||
# Enable HTTP/2
|
||||
# disable-http2: false
|
||||
|
||||
# Output configuration
|
||||
output:
|
||||
# Silent mode (only show findings)
|
||||
silent: false
|
||||
|
||||
# Verbose mode (detailed output)
|
||||
verbose: false
|
||||
|
||||
# No color output
|
||||
no-color: false
|
||||
|
||||
# JSON output
|
||||
json: false
|
||||
|
||||
# JSONL output (one JSON per line)
|
||||
jsonl: true
|
||||
|
||||
# SARIF output
|
||||
# sarif: true
|
||||
|
||||
# Markdown output
|
||||
# markdown: false
|
||||
|
||||
# Filtering configuration
|
||||
filters:
|
||||
# Exclude templates by ID
|
||||
# exclude-ids:
|
||||
# - template-id-1
|
||||
# - template-id-2
|
||||
|
||||
# Exclude templates by tag
|
||||
# exclude-tags:
|
||||
# - tech
|
||||
# - info
|
||||
|
||||
# Exclude severity levels
|
||||
# exclude-severity:
|
||||
# - info
|
||||
|
||||
# Include only specific tags
|
||||
# tags:
|
||||
# - cve
|
||||
# - owasp
|
||||
|
||||
# Include only specific templates
|
||||
# include-templates:
|
||||
# - /path/to/template.yaml
|
||||
|
||||
# Performance tuning
|
||||
performance:
|
||||
# Maximum number of templates to run
|
||||
# max-templates: 1000
|
||||
|
||||
# Maximum number of hosts to scan
|
||||
# max-hosts: 10000
|
||||
|
||||
# Memory optimization (reduces memory usage)
|
||||
# stream: true
|
||||
|
||||
# Disable update check
|
||||
# disable-update-check: false
|
||||
|
||||
# CI/CD specific settings
|
||||
ci:
|
||||
# Fail on findings (exit code 1 if vulnerabilities found)
|
||||
# fail-on-severity:
|
||||
# - critical
|
||||
# - high
|
||||
|
||||
# No interactive prompts
|
||||
# no-interaction: true
|
||||
|
||||
# Suppress progress bars
|
||||
# no-progress: true
|
||||
|
||||
# Authentication configuration
|
||||
authentication:
|
||||
# For authenticated scanning, use headers or custom authentication scripts
|
||||
# See authentication_patterns.md reference for details
|
||||
|
||||
# Example: Bearer token authentication
|
||||
# headers:
|
||||
# - "Authorization: Bearer ${API_TOKEN}"
|
||||
|
||||
# Example: Cookie-based authentication
|
||||
# headers:
|
||||
# - "Cookie: session=${SESSION_COOKIE}"
|
||||
|
||||
# Reporting configuration
|
||||
reporting:
|
||||
# Report directory
|
||||
# report-directory: ./nuclei-reports
|
||||
|
||||
# Report format
|
||||
# report-format: json
|
||||
|
||||
# Include timestamp in filenames
|
||||
# include-timestamp: true
|
||||
|
||||
# Advanced configuration
|
||||
advanced:
|
||||
# Follow host redirects (allow redirects to different hosts)
|
||||
# follow-host-redirects: false
|
||||
|
||||
# Maximum response body size to read (in KB)
|
||||
# max-response-size: 10240
|
||||
|
||||
# Include request/response in output
|
||||
# include-rr: false
|
||||
|
||||
# Store response
|
||||
# store-response: false
|
||||
|
||||
# Store response directory
|
||||
# store-response-dir: ./responses/
|
||||
|
||||
# Exclude configuration (global exclusions)
|
||||
exclude:
|
||||
# Exclude specific hosts
|
||||
# hosts:
|
||||
# - https://safe-domain.com
|
||||
# - https://third-party.com
|
||||
|
||||
# Exclude URL patterns (regex)
|
||||
# urls:
|
||||
# - ".*\\.js$"
|
||||
# - ".*\\.css$"
|
||||
# - ".*logout.*"
|
||||
|
||||
# Interactsh configuration (for OAST testing)
|
||||
interactsh:
|
||||
# Enable interactsh
|
||||
# enable: true
|
||||
|
||||
# Custom interactsh server
|
||||
# server: https://interact.sh
|
||||
|
||||
# Disable automatic polling
|
||||
# disable-polling: false
|
||||
|
||||
# Cloud configuration (for cloud-specific templates)
|
||||
cloud:
|
||||
# Enable cloud metadata service checks
|
||||
# enable-metadata: true
|
||||
|
||||
# Debug configuration
|
||||
debug:
|
||||
# Enable debug mode
|
||||
# enable: false
|
||||
|
||||
# Debug requests
|
||||
# debug-req: false
|
||||
|
||||
# Debug responses
|
||||
# debug-resp: false
|
||||
|
||||
# Example usage:
|
||||
# nuclei -u https://target.com -config nuclei_config.yaml
|
||||
355
skills/appsec/dast-nuclei/assets/rule-template.yaml
Normal file
355
skills/appsec/dast-nuclei/assets/rule-template.yaml
Normal file
@@ -0,0 +1,355 @@
|
||||
# Security Rule Template
|
||||
#
|
||||
# This template demonstrates how to structure security rules/policies.
|
||||
# Adapt this template to your specific security tool (Semgrep, OPA, etc.)
|
||||
#
|
||||
# Rule Structure Best Practices:
|
||||
# - Clear rule ID and metadata
|
||||
# - Severity classification
|
||||
# - Framework mappings (OWASP, CWE)
|
||||
# - Remediation guidance
|
||||
# - Example vulnerable and fixed code
|
||||
|
||||
rules:
|
||||
# Example Rule 1: SQL Injection Detection
|
||||
- id: sql-injection-string-concatenation
|
||||
metadata:
|
||||
name: "SQL Injection via String Concatenation"
|
||||
description: "Detects potential SQL injection vulnerabilities from string concatenation in SQL queries"
|
||||
severity: "HIGH"
|
||||
category: "security"
|
||||
subcategory: "injection"
|
||||
|
||||
# Security Framework Mappings
|
||||
owasp:
|
||||
- "A03:2021 - Injection"
|
||||
cwe:
|
||||
- "CWE-89: SQL Injection"
|
||||
mitre_attack:
|
||||
- "T1190: Exploit Public-Facing Application"
|
||||
|
||||
# Compliance Standards
|
||||
compliance:
|
||||
- "PCI-DSS 6.5.1: Injection flaws"
|
||||
- "NIST 800-53 SI-10: Information Input Validation"
|
||||
|
||||
# Confidence and Impact
|
||||
confidence: "HIGH"
|
||||
likelihood: "HIGH"
|
||||
impact: "HIGH"
|
||||
|
||||
# References
|
||||
references:
|
||||
- "https://owasp.org/www-community/attacks/SQL_Injection"
|
||||
- "https://cwe.mitre.org/data/definitions/89.html"
|
||||
- "https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html"
|
||||
|
||||
# Languages this rule applies to
|
||||
languages:
|
||||
- python
|
||||
- javascript
|
||||
- java
|
||||
- go
|
||||
|
||||
# Detection Pattern (example using Semgrep-style syntax)
|
||||
pattern-either:
|
||||
- pattern: |
|
||||
cursor.execute($SQL + $VAR)
|
||||
- pattern: |
|
||||
cursor.execute(f"... {$VAR} ...")
|
||||
- pattern: |
|
||||
cursor.execute("..." + $VAR + "...")
|
||||
|
||||
# What to report when found
|
||||
message: |
|
||||
Potential SQL injection vulnerability detected. SQL query is constructed using
|
||||
string concatenation or f-strings with user input. This allows attackers to
|
||||
inject malicious SQL code.
|
||||
|
||||
Use parameterized queries instead:
|
||||
- Python: cursor.execute("SELECT * FROM users WHERE id = ?", (user_id,))
|
||||
- JavaScript: db.query("SELECT * FROM users WHERE id = $1", [userId])
|
||||
|
||||
See: https://owasp.org/www-community/attacks/SQL_Injection
|
||||
|
||||
# Suggested fix (auto-fix if supported)
|
||||
fix: |
|
||||
Use parameterized queries with placeholders
|
||||
|
||||
# Example vulnerable code
|
||||
examples:
|
||||
- vulnerable: |
|
||||
# Vulnerable: String concatenation
|
||||
user_id = request.GET['id']
|
||||
query = "SELECT * FROM users WHERE id = " + user_id
|
||||
cursor.execute(query)
|
||||
|
||||
- fixed: |
|
||||
# Fixed: Parameterized query
|
||||
user_id = request.GET['id']
|
||||
query = "SELECT * FROM users WHERE id = ?"
|
||||
cursor.execute(query, (user_id,))
|
||||
|
||||
# Example Rule 2: Hardcoded Secrets Detection
|
||||
- id: hardcoded-secret-credential
|
||||
metadata:
|
||||
name: "Hardcoded Secret or Credential"
|
||||
description: "Detects hardcoded secrets, API keys, passwords, or tokens in source code"
|
||||
severity: "CRITICAL"
|
||||
category: "security"
|
||||
subcategory: "secrets"
|
||||
|
||||
owasp:
|
||||
- "A07:2021 - Identification and Authentication Failures"
|
||||
cwe:
|
||||
- "CWE-798: Use of Hard-coded Credentials"
|
||||
- "CWE-259: Use of Hard-coded Password"
|
||||
|
||||
compliance:
|
||||
- "PCI-DSS 8.2.1: Use of strong cryptography"
|
||||
- "SOC 2 CC6.1: Logical access controls"
|
||||
- "GDPR Article 32: Security of processing"
|
||||
|
||||
confidence: "MEDIUM"
|
||||
likelihood: "HIGH"
|
||||
impact: "CRITICAL"
|
||||
|
||||
references:
|
||||
- "https://cwe.mitre.org/data/definitions/798.html"
|
||||
- "https://owasp.org/www-community/vulnerabilities/Use_of_hard-coded_password"
|
||||
|
||||
languages:
|
||||
- python
|
||||
- javascript
|
||||
- java
|
||||
- go
|
||||
- ruby
|
||||
|
||||
pattern-either:
|
||||
- pattern: |
|
||||
password = "..."
|
||||
- pattern: |
|
||||
api_key = "..."
|
||||
- pattern: |
|
||||
secret = "..."
|
||||
- pattern: |
|
||||
token = "..."
|
||||
|
||||
pattern-not: |
|
||||
$VAR = ""
|
||||
|
||||
message: |
|
||||
Potential hardcoded secret detected. Hardcoding credentials in source code
|
||||
is a critical security vulnerability that can lead to unauthorized access
|
||||
if the code is exposed.
|
||||
|
||||
Use environment variables or a secrets management system instead:
|
||||
- Python: os.environ.get('API_KEY')
|
||||
- Node.js: process.env.API_KEY
|
||||
- Secrets Manager: AWS Secrets Manager, HashiCorp Vault, etc.
|
||||
|
||||
See: https://cwe.mitre.org/data/definitions/798.html
|
||||
|
||||
examples:
|
||||
- vulnerable: |
|
||||
# Vulnerable: Hardcoded API key
|
||||
api_key = "sk-1234567890abcdef"
|
||||
api.authenticate(api_key)
|
||||
|
||||
- fixed: |
|
||||
# Fixed: Environment variable
|
||||
import os
|
||||
api_key = os.environ.get('API_KEY')
|
||||
if not api_key:
|
||||
raise ValueError("API_KEY environment variable not set")
|
||||
api.authenticate(api_key)
|
||||
|
||||
# Example Rule 3: XSS via Unsafe HTML Rendering
|
||||
- id: xss-unsafe-html-rendering
|
||||
metadata:
|
||||
name: "Cross-Site Scripting (XSS) via Unsafe HTML"
|
||||
description: "Detects unsafe HTML rendering that could lead to XSS vulnerabilities"
|
||||
severity: "HIGH"
|
||||
category: "security"
|
||||
subcategory: "xss"
|
||||
|
||||
owasp:
|
||||
- "A03:2021 - Injection"
|
||||
cwe:
|
||||
- "CWE-79: Cross-site Scripting (XSS)"
|
||||
- "CWE-80: Improper Neutralization of Script-Related HTML Tags"
|
||||
|
||||
compliance:
|
||||
- "PCI-DSS 6.5.7: Cross-site scripting"
|
||||
- "NIST 800-53 SI-10: Information Input Validation"
|
||||
|
||||
confidence: "HIGH"
|
||||
likelihood: "MEDIUM"
|
||||
impact: "HIGH"
|
||||
|
||||
references:
|
||||
- "https://owasp.org/www-community/attacks/xss/"
|
||||
- "https://cwe.mitre.org/data/definitions/79.html"
|
||||
- "https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html"
|
||||
|
||||
languages:
|
||||
- javascript
|
||||
- typescript
|
||||
- jsx
|
||||
- tsx
|
||||
|
||||
pattern-either:
|
||||
- pattern: |
|
||||
dangerouslySetInnerHTML={{__html: $VAR}}
|
||||
- pattern: |
|
||||
innerHTML = $VAR
|
||||
|
||||
message: |
|
||||
Potential XSS vulnerability detected. Setting HTML content directly from
|
||||
user input without sanitization can allow attackers to inject malicious
|
||||
JavaScript code.
|
||||
|
||||
Use one of these safe alternatives:
|
||||
- React: Use {userInput} for automatic escaping
|
||||
- DOMPurify: const clean = DOMPurify.sanitize(dirty);
|
||||
- Framework-specific sanitizers
|
||||
|
||||
See: https://owasp.org/www-community/attacks/xss/
|
||||
|
||||
examples:
|
||||
- vulnerable: |
|
||||
// Vulnerable: Unsanitized HTML
|
||||
function UserComment({ comment }) {
|
||||
return <div dangerouslySetInnerHTML={{__html: comment}} />;
|
||||
}
|
||||
|
||||
- fixed: |
|
||||
// Fixed: Sanitized with DOMPurify
|
||||
import DOMPurify from 'dompurify';
|
||||
|
||||
function UserComment({ comment }) {
|
||||
const sanitized = DOMPurify.sanitize(comment);
|
||||
return <div dangerouslySetInnerHTML={{__html: sanitized}} />;
|
||||
}
|
||||
|
||||
# Example Rule 4: Insecure Cryptography
|
||||
- id: weak-cryptographic-algorithm
|
||||
metadata:
|
||||
name: "Weak Cryptographic Algorithm"
|
||||
description: "Detects use of weak or deprecated cryptographic algorithms"
|
||||
severity: "HIGH"
|
||||
category: "security"
|
||||
subcategory: "cryptography"
|
||||
|
||||
owasp:
|
||||
- "A02:2021 - Cryptographic Failures"
|
||||
cwe:
|
||||
- "CWE-327: Use of a Broken or Risky Cryptographic Algorithm"
|
||||
- "CWE-326: Inadequate Encryption Strength"
|
||||
|
||||
compliance:
|
||||
- "PCI-DSS 4.1: Use strong cryptography"
|
||||
- "NIST 800-53 SC-13: Cryptographic Protection"
|
||||
- "GDPR Article 32: Security of processing"
|
||||
|
||||
confidence: "HIGH"
|
||||
likelihood: "MEDIUM"
|
||||
impact: "HIGH"
|
||||
|
||||
references:
|
||||
- "https://cwe.mitre.org/data/definitions/327.html"
|
||||
- "https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/09-Testing_for_Weak_Cryptography/"
|
||||
|
||||
languages:
|
||||
- python
|
||||
- javascript
|
||||
- java
|
||||
|
||||
pattern-either:
|
||||
- pattern: |
|
||||
hashlib.md5(...)
|
||||
- pattern: |
|
||||
hashlib.sha1(...)
|
||||
- pattern: |
|
||||
crypto.createHash('md5')
|
||||
- pattern: |
|
||||
crypto.createHash('sha1')
|
||||
|
||||
message: |
|
||||
Weak cryptographic algorithm detected (MD5 or SHA1). These algorithms are
|
||||
considered cryptographically broken and should not be used for security purposes.
|
||||
|
||||
Use strong alternatives:
|
||||
- For hashing: SHA-256, SHA-384, or SHA-512
|
||||
- For password hashing: bcrypt, argon2, or PBKDF2
|
||||
- Python: hashlib.sha256()
|
||||
- Node.js: crypto.createHash('sha256')
|
||||
|
||||
See: https://cwe.mitre.org/data/definitions/327.html
|
||||
|
||||
examples:
|
||||
- vulnerable: |
|
||||
# Vulnerable: MD5 hash
|
||||
import hashlib
|
||||
hash_value = hashlib.md5(data).hexdigest()
|
||||
|
||||
- fixed: |
|
||||
# Fixed: SHA-256 hash
|
||||
import hashlib
|
||||
hash_value = hashlib.sha256(data).hexdigest()
|
||||
|
||||
# Rule Configuration
|
||||
configuration:
|
||||
# Global settings
|
||||
enabled: true
|
||||
severity_threshold: "MEDIUM" # Report findings at MEDIUM severity and above
|
||||
|
||||
# Performance tuning
|
||||
max_file_size_kb: 1024
|
||||
exclude_patterns:
|
||||
- "test/*"
|
||||
- "tests/*"
|
||||
- "node_modules/*"
|
||||
- "vendor/*"
|
||||
- "*.min.js"
|
||||
|
||||
# False positive reduction
|
||||
confidence_threshold: "MEDIUM" # Only report findings with MEDIUM confidence or higher
|
||||
|
||||
# Rule Metadata Schema
|
||||
# This section documents the expected structure for rules
|
||||
metadata_schema:
|
||||
required:
|
||||
- id: "Unique identifier for the rule (kebab-case)"
|
||||
- name: "Human-readable rule name"
|
||||
- description: "What the rule detects"
|
||||
- severity: "CRITICAL | HIGH | MEDIUM | LOW | INFO"
|
||||
- category: "security | best-practice | performance"
|
||||
|
||||
optional:
|
||||
- subcategory: "Specific type (injection, xss, secrets, etc.)"
|
||||
- owasp: "OWASP Top 10 mappings"
|
||||
- cwe: "CWE identifier(s)"
|
||||
- mitre_attack: "MITRE ATT&CK technique(s)"
|
||||
- compliance: "Compliance standard references"
|
||||
- confidence: "Detection confidence level"
|
||||
- likelihood: "Likelihood of exploitation"
|
||||
- impact: "Potential impact if exploited"
|
||||
- references: "External documentation links"
|
||||
|
||||
# Usage Instructions:
|
||||
#
|
||||
# 1. Copy this template when creating new security rules
|
||||
# 2. Update metadata fields with appropriate framework mappings
|
||||
# 3. Customize detection patterns for your tool (Semgrep, OPA, etc.)
|
||||
# 4. Provide clear remediation guidance in the message field
|
||||
# 5. Include both vulnerable and fixed code examples
|
||||
# 6. Test rules on real codebases before deployment
|
||||
#
|
||||
# Best Practices:
|
||||
# - Map to multiple frameworks (OWASP, CWE, MITRE ATT&CK)
|
||||
# - Include compliance standard references
|
||||
# - Provide actionable remediation guidance
|
||||
# - Show code examples (vulnerable vs. fixed)
|
||||
# - Tune confidence levels to reduce false positives
|
||||
# - Exclude test directories to reduce noise
|
||||
Reference in New Issue
Block a user