Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 17:51:02 +08:00
commit ff1f4bd119
252 changed files with 72682 additions and 0 deletions

View File

@@ -0,0 +1,708 @@
---
name: api-spectral
description: >
API specification linting and security validation using Stoplight's Spectral with support for
OpenAPI, AsyncAPI, and Arazzo specifications. Validates API definitions against security best
practices, OWASP API Security Top 10, and custom organizational standards. Use when: (1) Validating
OpenAPI/AsyncAPI specifications for security issues and design flaws, (2) Enforcing API design
standards and governance policies across API portfolios, (3) Creating custom security rules for
API specifications in CI/CD pipelines, (4) Detecting authentication, authorization, and data
exposure issues in API definitions, (5) Ensuring API specifications comply with organizational
security standards and regulatory requirements.
version: 0.1.0
maintainer: SirAppSec
category: appsec
tags: [api-security, openapi, asyncapi, linting, spectral, api-governance, owasp-api, specification-validation]
frameworks: [OWASP]
dependencies:
tools: [node, npm]
optional: [docker, git]
references:
- https://docs.stoplight.io/docs/spectral/674b27b261c3c-overview
- https://github.com/stoplightio/spectral
- https://owasp.org/API-Security/editions/2023/en/0x11-t10/
---
# API Security with Spectral
## Overview
Spectral is a flexible JSON/YAML linter from Stoplight that validates API specifications against
security best practices and organizational standards. With built-in rulesets for OpenAPI v2/v3.x,
AsyncAPI v2.x, and Arazzo v1.0, Spectral helps identify security vulnerabilities, design flaws,
and compliance issues during the API design phase—before code is written. Custom rulesets enable
enforcement of OWASP API Security Top 10 patterns, authentication standards, and data protection
requirements across your entire API portfolio.
## Quick Start
### Installation
```bash
# Install via npm
npm install -g @stoplight/spectral-cli
# Or using Yarn
yarn global add @stoplight/spectral-cli
# Or using Docker
docker pull stoplight/spectral
# Verify installation
spectral --version
```
### Basic API Specification Linting
```bash
# Lint OpenAPI specification with built-in rules
spectral lint openapi.yaml
# Lint with specific ruleset
spectral lint openapi.yaml --ruleset .spectral.yaml
# Output as JSON for CI/CD integration
spectral lint openapi.yaml --format json --output results.json
```
### Quick Security Scan
```bash
# Create security-focused ruleset
echo 'extends: ["spectral:oas"]' > .spectral.yaml
# Lint API specification
spectral lint api-spec.yaml --ruleset .spectral.yaml
```
## Core Workflow
### Workflow Checklist
Progress:
[ ] 1. Install Spectral and select appropriate base rulesets
[ ] 2. Create or configure ruleset with security rules
[ ] 3. Identify API specifications to validate (OpenAPI, AsyncAPI, Arazzo)
[ ] 4. Run linting with appropriate severity thresholds
[ ] 5. Review findings and categorize by security impact
[ ] 6. Map findings to OWASP API Security Top 10
[ ] 7. Create custom rules for organization-specific security patterns
[ ] 8. Integrate into CI/CD pipeline with failure thresholds
[ ] 9. Generate reports with remediation guidance
[ ] 10. Establish continuous validation process
Work through each step systematically. Check off completed items.
### Step 1: Ruleset Configuration
Create a `.spectral.yaml` ruleset extending built-in security rules:
```yaml
# .spectral.yaml - Basic security-focused ruleset
extends: ["spectral:oas", "spectral:asyncapi"]
rules:
# Enforce HTTPS for all API endpoints
oas3-valid-schema-example: true
oas3-server-not-example.com: true
# Authentication security
operation-security-defined: error
# Information disclosure prevention
info-contact: warn
info-description: warn
```
**Built-in Rulesets:**
- `spectral:oas` - OpenAPI v2/v3.x security and best practices
- `spectral:asyncapi` - AsyncAPI v2.x validation rules
- `spectral:arazzo` - Arazzo v1.0 workflow specifications
**Ruleset Selection Best Practices:**
- Start with built-in rulesets and progressively add custom rules
- Use `error` severity for critical security issues (authentication, HTTPS)
- Use `warn` for recommended practices and information disclosure risks
- Use `info` for style guide compliance and documentation completeness
For advanced ruleset patterns, see `references/ruleset_patterns.md`.
### Step 2: Security-Focused API Linting
Run Spectral with security-specific validation:
```bash
# Comprehensive security scan
spectral lint openapi.yaml \
--ruleset .spectral.yaml \
--format stylish \
--verbose
# Focus on error-level findings only (critical security issues)
spectral lint openapi.yaml \
--ruleset .spectral.yaml \
--fail-severity error
# Scan multiple specifications
spectral lint api-specs/*.yaml --ruleset .spectral.yaml
# Generate JSON report for further analysis
spectral lint openapi.yaml \
--ruleset .spectral.yaml \
--format json \
--output security-findings.json
```
**Output Formats:**
- `stylish` - Human-readable terminal output (default)
- `json` - Machine-readable JSON for CI/CD integration
- `junit` - JUnit XML for test reporting platforms
- `html` - HTML report (requires additional plugins)
- `github-actions` - GitHub Actions annotations format
### Step 3: OWASP API Security Validation
Validate API specifications against OWASP API Security Top 10:
```yaml
# .spectral-owasp.yaml - OWASP API Security focused rules
extends: ["spectral:oas"]
rules:
# API1:2023 - Broken Object Level Authorization
operation-security-defined:
severity: error
message: "All operations must have security defined (OWASP API1)"
# API2:2023 - Broken Authentication
security-schemes-defined:
severity: error
message: "API must define security schemes (OWASP API2)"
# API3:2023 - Broken Object Property Level Authorization
no-additional-properties:
severity: warn
message: "Consider disabling additionalProperties to prevent data leakage (OWASP API3)"
# API5:2023 - Broken Function Level Authorization
operation-tag-defined:
severity: warn
message: "Operations should be tagged for authorization policy mapping (OWASP API5)"
# API7:2023 - Server Side Request Forgery
no-http-basic:
severity: error
message: "HTTP Basic auth transmits credentials in plain text (OWASP API7)"
# API8:2023 - Security Misconfiguration
servers-use-https:
description: All server URLs must use HTTPS
severity: error
given: $.servers[*].url
then:
function: pattern
functionOptions:
match: "^https://"
message: "Server URL must use HTTPS (OWASP API8)"
# API9:2023 - Improper Inventory Management
api-version-required:
severity: error
given: $.info
then:
field: version
function: truthy
message: "API version must be specified (OWASP API9)"
```
**Run OWASP-focused validation:**
```bash
spectral lint openapi.yaml --ruleset .spectral-owasp.yaml
```
For complete OWASP API Security Top 10 rule mappings, see `references/owasp_api_mappings.md`.
### Step 4: Custom Security Rule Development
Create organization-specific security rules using Spectral's rule engine:
```yaml
# .spectral-custom.yaml
extends: ["spectral:oas"]
rules:
# Require API key authentication
require-api-key-auth:
description: All APIs must support API key authentication
severity: error
given: $.components.securitySchemes[*]
then:
field: type
function: enumeration
functionOptions:
values: [apiKey, oauth2, openIdConnect]
message: "API must define apiKey, OAuth2, or OpenID Connect security"
# Prevent PII in query parameters
no-pii-in-query:
description: Prevent PII exposure in URL query parameters
severity: error
given: $.paths[*][*].parameters[?(@.in == 'query')].name
then:
function: pattern
functionOptions:
notMatch: "(ssn|social.?security|credit.?card|password|secret|token)"
message: "Query parameters must not contain PII identifiers"
# Require rate limiting headers
require-rate-limit-headers:
description: API responses should include rate limit headers
severity: warn
given: $.paths[*][*].responses[*].headers
then:
function: schema
functionOptions:
schema:
type: object
properties:
X-RateLimit-Limit: true
X-RateLimit-Remaining: true
message: "Consider adding rate limit headers for security"
# Enforce consistent error responses
error-response-format:
description: Error responses must follow standard format
severity: error
given: $.paths[*][*].responses[?(@property >= 400)].content.application/json.schema
then:
function: schema
functionOptions:
schema:
type: object
required: [error, message]
properties:
error:
type: string
message:
type: string
message: "Error responses must include 'error' and 'message' fields"
```
**Custom Rule Development Resources:**
- `references/custom_rules_guide.md` - Complete rule authoring guide with functions
- `references/custom_functions.md` - Creating custom JavaScript/TypeScript functions
- `assets/rule-templates/` - Reusable rule templates for common security patterns
### Step 5: CI/CD Pipeline Integration
Integrate Spectral into continuous integration workflows:
**GitHub Actions:**
```yaml
# .github/workflows/api-security-lint.yml
name: API Security Linting
on: [push, pull_request]
jobs:
spectral:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install Spectral
run: npm install -g @stoplight/spectral-cli
- name: Lint API Specifications
run: |
spectral lint api-specs/*.yaml \
--ruleset .spectral.yaml \
--format github-actions \
--fail-severity error
- name: Generate Report
if: always()
run: |
spectral lint api-specs/*.yaml \
--ruleset .spectral.yaml \
--format json \
--output spectral-report.json
- name: Upload Report
if: always()
uses: actions/upload-artifact@v3
with:
name: spectral-security-report
path: spectral-report.json
```
**GitLab CI:**
```yaml
# .gitlab-ci.yml
api-security-lint:
stage: test
image: node:18
script:
- npm install -g @stoplight/spectral-cli
- spectral lint api-specs/*.yaml --ruleset .spectral.yaml --fail-severity error
artifacts:
when: always
reports:
junit: spectral-report.xml
```
**Docker-Based Pipeline:**
```bash
# Run in CI/CD with Docker
docker run --rm \
-v $(pwd):/work \
stoplight/spectral lint /work/openapi.yaml \
--ruleset /work/.spectral.yaml \
--format json \
--output /work/results.json
# Fail build on critical security issues
if jq -e '.[] | select(.severity == 0)' results.json > /dev/null; then
echo "Critical security issues detected!"
exit 1
fi
```
For complete CI/CD integration examples, see `scripts/ci_integration_examples/`.
### Step 6: Results Analysis and Remediation
Analyze findings and provide security remediation:
```bash
# Parse Spectral JSON output for security report
python3 scripts/parse_spectral_results.py \
--input spectral-report.json \
--output security-report.html \
--map-owasp \
--severity-threshold error
# Generate remediation guidance
python3 scripts/generate_remediation.py \
--input spectral-report.json \
--output remediation-guide.md
```
**Validation Workflow:**
1. Review all error-level findings (critical security issues)
2. Verify each finding in API specification context
3. Map findings to OWASP API Security Top 10 categories
4. Prioritize by severity and exploitability
5. Apply fixes to API specifications
6. Re-lint to verify remediation
7. Document security decisions and exceptions
**Feedback Loop Pattern:**
```bash
# 1. Initial lint
spectral lint openapi.yaml --ruleset .spectral.yaml -o scan1.json
# 2. Apply security fixes to API specification
# 3. Re-lint to verify fixes
spectral lint openapi.yaml --ruleset .spectral.yaml -o scan2.json
# 4. Compare results
python3 scripts/compare_spectral_results.py scan1.json scan2.json
```
## Advanced Patterns
### Pattern 1: Multi-Specification Governance
Enforce consistent security standards across API portfolio:
```bash
# Scan all API specifications with organization ruleset
find api-specs/ -name "*.yaml" -o -name "*.json" | while read spec; do
echo "Linting: $spec"
spectral lint "$spec" \
--ruleset .spectral-org-standards.yaml \
--format json \
--output "reports/$(basename $spec .yaml)-report.json"
done
# Aggregate findings across portfolio
python3 scripts/aggregate_api_findings.py \
--input-dir reports/ \
--output portfolio-security-report.html
```
### Pattern 2: Progressive Severity Enforcement
Start with warnings and progressively enforce stricter rules:
```yaml
# .spectral-phase1.yaml - Initial rollout (warnings only)
extends: ["spectral:oas"]
rules:
servers-use-https: warn
operation-security-defined: warn
# .spectral-phase2.yaml - Enforcement phase (errors)
extends: ["spectral:oas"]
rules:
servers-use-https: error
operation-security-defined: error
```
```bash
# Phase 1: Awareness (don't fail builds)
spectral lint openapi.yaml --ruleset .spectral-phase1.yaml
# Phase 2: Enforcement (fail on violations)
spectral lint openapi.yaml --ruleset .spectral-phase2.yaml --fail-severity error
```
### Pattern 3: API Security Pre-Commit Validation
Prevent insecure API specifications from being committed:
```bash
# .git/hooks/pre-commit
#!/bin/bash
# Find staged API specification files
SPECS=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(yaml|yml|json)$' | grep -E '(openapi|swagger|api)')
if [ -n "$SPECS" ]; then
echo "Validating API specifications..."
for spec in $SPECS; do
spectral lint "$spec" --ruleset .spectral.yaml --fail-severity error
if [ $? -ne 0 ]; then
echo "Security validation failed for $spec"
exit 1
fi
done
fi
```
### Pattern 4: Automated Security Review Comments
Generate security review comments for pull requests:
```bash
# Generate PR review comments from Spectral findings
spectral lint openapi.yaml \
--ruleset .spectral.yaml \
--format json | \
python3 scripts/generate_pr_comments.py \
--file openapi.yaml \
--severity error,warn \
--output pr-comments.json
# Post to GitHub PR via gh CLI
gh pr comment $PR_NUMBER --body-file pr-comments.json
```
## Custom Functions for Advanced Security Rules
Create custom JavaScript functions for complex security validation:
```javascript
// spectral-functions/check-jwt-expiry.js
export default (targetVal, opts) => {
// Validate JWT security scheme includes expiration
if (targetVal.type === 'http' && targetVal.scheme === 'bearer') {
if (!targetVal.bearerFormat || targetVal.bearerFormat !== 'JWT') {
return [{
message: 'Bearer authentication should specify JWT format'
}];
}
}
return [];
};
```
```yaml
# .spectral.yaml with custom function
functions:
- check-jwt-expiry
functionsDir: ./spectral-functions
rules:
jwt-security-check:
description: Validate JWT security configuration
severity: error
given: $.components.securitySchemes[*]
then:
function: check-jwt-expiry
```
For complete custom function development guide, see `references/custom_functions.md`.
## Automation & Continuous Validation
### Scheduled API Security Scanning
```bash
# Automated daily API specification scanning
./scripts/spectral_scheduler.sh \
--schedule daily \
--specs-dir api-specs/ \
--ruleset .spectral-owasp.yaml \
--output-dir scan-results/ \
--alert-on error \
--slack-webhook $SLACK_WEBHOOK
```
### API Specification Monitoring
```bash
# Monitor API specifications for security regressions
./scripts/spectral_monitor.sh \
--baseline baseline-scan.json \
--current-scan latest-scan.json \
--alert-on-new-findings \
--email security-team@example.com
```
## Security Considerations
- **Specification Security**: API specifications may contain sensitive information (internal URLs, authentication schemes) - control access and sanitize before sharing
- **Rule Integrity**: Protect ruleset files from unauthorized modification - store in version control with code review requirements
- **False Positives**: Manually review findings before making security claims - context matters for API design decisions
- **Specification Versioning**: Maintain version history of API specifications to track security improvements over time
- **Secrets in Specs**: Never include actual credentials, API keys, or secrets in example values - use placeholder values only
- **Compliance Mapping**: Document how Spectral rules map to compliance requirements (PCI-DSS, GDPR, HIPAA)
- **Governance Enforcement**: Define exception process for legitimate rule violations with security team approval
- **Audit Logging**: Log all Spectral scans, findings, and remediation actions for security auditing
- **Access Control**: Restrict modification of security rulesets to designated API security team members
- **Continuous Validation**: Re-validate API specifications whenever they change or when new security rules are added
## Bundled Resources
### Scripts (`scripts/`)
- `parse_spectral_results.py` - Parse Spectral JSON output and generate security reports with OWASP mapping
- `generate_remediation.py` - Generate remediation guidance based on Spectral findings
- `compare_spectral_results.py` - Compare two Spectral scans to track remediation progress
- `aggregate_api_findings.py` - Aggregate findings across multiple API specifications
- `spectral_ci.sh` - CI/CD integration wrapper with exit code handling
- `spectral_scheduler.sh` - Scheduled scanning with alerting
- `spectral_monitor.sh` - Continuous monitoring with baseline comparison
- `generate_pr_comments.py` - Convert Spectral findings to PR review comments
### References (`references/`)
- `owasp_api_mappings.md` - Complete OWASP API Security Top 10 rule mappings
- `custom_rules_guide.md` - Custom rule authoring with examples
- `custom_functions.md` - Creating custom JavaScript/TypeScript validation functions
- `ruleset_patterns.md` - Reusable ruleset patterns for common security scenarios
- `api_security_checklist.md` - API security validation checklist
### Assets (`assets/`)
- `spectral-owasp.yaml` - Comprehensive OWASP API Security Top 10 ruleset
- `spectral-org-template.yaml` - Organization-wide API security standards template
- `github-actions-template.yml` - Complete GitHub Actions workflow
- `gitlab-ci-template.yml` - GitLab CI integration template
- `rule-templates/` - Reusable security rule templates
## Common Patterns
### Pattern 1: Security-First API Design Validation
Validate API specifications during design phase:
```bash
# Design phase validation (strict security rules)
spectral lint api-design.yaml \
--ruleset .spectral-owasp.yaml \
--fail-severity warn \
--verbose
```
### Pattern 2: API Specification Diff Analysis
Detect security regressions between API versions:
```bash
# Compare two API specification versions
spectral lint api-v2.yaml --ruleset .spectral.yaml -o v2-findings.json
spectral lint api-v1.yaml --ruleset .spectral.yaml -o v1-findings.json
python3 scripts/compare_spectral_results.py \
--baseline v1-findings.json \
--current v2-findings.json \
--show-regressions
```
### Pattern 3: Multi-Environment API Security
Different rulesets for development, staging, production:
```yaml
# .spectral-dev.yaml (permissive)
extends: ["spectral:oas"]
rules:
servers-use-https: warn
# .spectral-prod.yaml (strict)
extends: ["spectral:oas"]
rules:
servers-use-https: error
operation-security-defined: error
```
## Integration Points
- **CI/CD**: GitHub Actions, GitLab CI, Jenkins, CircleCI, Azure DevOps
- **API Gateways**: Kong, Apigee, AWS API Gateway (validate specs before deployment)
- **IDE Integration**: VS Code extension, JetBrains plugins for real-time validation
- **API Documentation**: Stoplight Studio, Swagger UI, Redoc
- **Issue Tracking**: Jira, GitHub Issues, Linear (automated ticket creation for findings)
- **API Governance**: Backstage, API catalogs (enforce standards across portfolios)
- **Security Platforms**: Defect Dojo, SIEM platforms (via JSON export)
## Troubleshooting
### Issue: Too Many False Positives
**Solution**:
- Start with `error` severity only: `spectral lint --fail-severity error`
- Progressively add rules and adjust severity levels
- Use `overrides` section in ruleset to exclude specific paths
- See `references/ruleset_patterns.md` for filtering strategies
### Issue: Custom Rules Not Working
**Solution**:
- Verify JSONPath expressions using online JSONPath testers
- Check rule syntax with `spectral lint --ruleset .spectral.yaml --verbose`
- Use `--verbose` flag to see which rules are being applied
- Test rules in isolation before combining them
### Issue: Performance Issues with Large Specifications
**Solution**:
- Lint specific paths only: `spectral lint api-spec.yaml --ignore-paths "components/examples"`
- Use `--skip-rules` to disable expensive rules temporarily
- Split large specifications into smaller modules
- Run Spectral in parallel for multiple specifications
### Issue: CI/CD Integration Failing
**Solution**:
- Check Node.js version compatibility (requires Node 14+)
- Verify ruleset path is correct relative to specification file
- Use `--fail-severity` to control when builds should fail
- Review exit codes in `scripts/spectral_ci.sh`
## References
- [Spectral Documentation](https://docs.stoplight.io/docs/spectral/674b27b261c3c-overview)
- [Spectral GitHub Repository](https://github.com/stoplightio/spectral)
- [OWASP API Security Top 10](https://owasp.org/API-Security/editions/2023/en/0x11-t10/)
- [OpenAPI Specification](https://spec.openapis.org/oas/latest.html)
- [AsyncAPI Specification](https://www.asyncapi.com/docs/reference/specification/latest)

View 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.

View 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

View File

@@ -0,0 +1,189 @@
# GitHub Actions Workflow for Spectral API Security Linting
# This workflow validates OpenAPI/AsyncAPI specifications against security best practices
name: API Security Linting with Spectral
on:
push:
branches: [main, develop]
paths:
- 'api-specs/**/*.yaml'
- 'api-specs/**/*.yml'
- 'api-specs/**/*.json'
- '.spectral.yaml'
pull_request:
branches: [main, develop]
paths:
- 'api-specs/**/*.yaml'
- 'api-specs/**/*.yml'
- 'api-specs/**/*.json'
- '.spectral.yaml'
jobs:
spectral-lint:
name: Lint API Specifications
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install Spectral CLI
run: npm install -g @stoplight/spectral-cli
- name: Verify Spectral Installation
run: spectral --version
- name: Lint API Specifications (GitHub Actions Format)
run: |
spectral lint api-specs/**/*.{yaml,yml,json} \
--ruleset .spectral.yaml \
--format github-actions \
--fail-severity error
continue-on-error: true
- name: Generate JSON Report
if: always()
run: |
mkdir -p reports
spectral lint api-specs/**/*.{yaml,yml,json} \
--ruleset .spectral.yaml \
--format json \
--output reports/spectral-results.json || true
- name: Generate HTML Report
if: always()
run: |
# Download parse script if not in repository
if [ ! -f "scripts/parse_spectral_results.py" ]; then
curl -o scripts/parse_spectral_results.py \
https://raw.githubusercontent.com/SecOpsAgentKit/skills/main/appsec/api-spectral/scripts/parse_spectral_results.py
chmod +x scripts/parse_spectral_results.py
fi
python3 scripts/parse_spectral_results.py \
--input reports/spectral-results.json \
--output reports/spectral-report.html \
--format html \
--map-owasp
- name: Upload Spectral Reports
if: always()
uses: actions/upload-artifact@v4
with:
name: spectral-security-reports
path: reports/
retention-days: 30
- name: Check for Critical Issues
run: |
if [ -f "reports/spectral-results.json" ]; then
CRITICAL_COUNT=$(jq '[.[] | select(.severity == 0)] | length' reports/spectral-results.json)
echo "Critical security issues found: $CRITICAL_COUNT"
if [ "$CRITICAL_COUNT" -gt 0 ]; then
echo "::error::Found $CRITICAL_COUNT critical security issues in API specifications"
exit 1
fi
fi
- name: Comment PR with Results
if: github.event_name == 'pull_request' && always()
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
if (fs.existsSync('reports/spectral-results.json')) {
const results = JSON.parse(fs.readFileSync('reports/spectral-results.json', 'utf8'));
const severityCounts = results.reduce((acc, finding) => {
const severity = ['error', 'warn', 'info', 'hint'][finding.severity] || 'unknown';
acc[severity] = (acc[severity] || 0) + 1;
return acc;
}, {});
const errorCount = severityCounts.error || 0;
const warnCount = severityCounts.warn || 0;
const infoCount = severityCounts.info || 0;
const summary = `## 🔒 API Security Lint Results
**Total Findings:** ${results.length}
| Severity | Count |
|----------|-------|
| 🔴 Error | ${errorCount} |
| 🟡 Warning | ${warnCount} |
| 🔵 Info | ${infoCount} |
${errorCount > 0 ? '⚠️ **Action Required:** Fix error-level security issues before merging.' : '✅ No critical security issues found.'}
📄 [View Detailed Report](../actions/runs/${context.runId})
`;
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: summary
});
}
# Optional: Separate job for OWASP-specific validation
owasp-validation:
name: OWASP API Security Validation
runs-on: ubuntu-latest
needs: spectral-lint
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install Spectral CLI
run: npm install -g @stoplight/spectral-cli
- name: Validate Against OWASP Ruleset
run: |
# Use OWASP-specific ruleset if available
if [ -f ".spectral-owasp.yaml" ]; then
RULESET=".spectral-owasp.yaml"
else
# Download OWASP ruleset template
curl -o .spectral-owasp.yaml \
https://raw.githubusercontent.com/SecOpsAgentKit/skills/main/appsec/api-spectral/assets/spectral-owasp.yaml
RULESET=".spectral-owasp.yaml"
fi
spectral lint api-specs/**/*.{yaml,yml,json} \
--ruleset "$RULESET" \
--format stylish \
--fail-severity warn
- name: Generate OWASP Compliance Report
if: always()
run: |
mkdir -p reports
spectral lint api-specs/**/*.{yaml,yml,json} \
--ruleset .spectral-owasp.yaml \
--format json \
--output reports/owasp-validation.json || true
- name: Upload OWASP Report
if: always()
uses: actions/upload-artifact@v4
with:
name: owasp-compliance-report
path: reports/owasp-validation.json
retention-days: 30

View 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

View File

@@ -0,0 +1,293 @@
# Comprehensive OWASP API Security Top 10 2023 Spectral Ruleset
# This ruleset enforces OWASP API Security best practices for OpenAPI specifications
extends: ["spectral:oas"]
rules:
# ============================================================================
# API1:2023 - Broken Object Level Authorization
# ============================================================================
operation-security-defined:
description: All operations must have security requirements defined (OWASP API1)
severity: error
given: $.paths[*][get,post,put,patch,delete,head]
then:
- field: security
function: truthy
message: "Operations must define security requirements to prevent unauthorized object access (OWASP API1:2023 - Broken Object Level Authorization)"
id-parameters-require-security:
description: Operations with ID parameters must have security defined
severity: error
given: $.paths[?(@property =~ /(\/\{id\}|\/\{.*[_-]id\})/i)][get,put,patch,delete]
then:
- field: security
function: truthy
message: "Operations with ID parameters require security to prevent IDOR vulnerabilities (OWASP API1:2023)"
# ============================================================================
# API2:2023 - Broken Authentication
# ============================================================================
security-schemes-required:
description: API must define security schemes (OWASP API2)
severity: error
given: $.components
then:
- field: securitySchemes
function: truthy
message: "API must define security schemes to prevent authentication bypass (OWASP API2:2023 - Broken Authentication)"
no-http-basic-auth:
description: HTTP Basic authentication is insecure for APIs
severity: error
given: $.components.securitySchemes[*]
then:
- field: scheme
function: pattern
functionOptions:
notMatch: "^basic$"
message: "HTTP Basic authentication transmits credentials in plain text - use OAuth2, API key, or JWT (OWASP API2:2023)"
bearer-format-specified:
description: Bearer authentication should specify token format (JWT recommended)
severity: warn
given: $.components.securitySchemes[?(@.type == 'http' && @.scheme == 'bearer')]
then:
- field: bearerFormat
function: truthy
message: "Bearer authentication should specify token format (bearerFormat: JWT) for clarity (OWASP API2:2023)"
# ============================================================================
# API3:2023 - Broken Object Property Level Authorization
# ============================================================================
no-additional-properties:
description: Prevent mass assignment by disabling additionalProperties
severity: warn
given: $.components.schemas[?(@.type == 'object')]
then:
- field: additionalProperties
function: falsy
message: "Set additionalProperties to false to prevent mass assignment vulnerabilities (OWASP API3:2023 - Broken Object Property Level Authorization)"
schemas-have-properties:
description: Object schemas should explicitly define properties
severity: warn
given: $.components.schemas[?(@.type == 'object')]
then:
- field: properties
function: truthy
message: "Explicitly define object properties to control data exposure (OWASP API3:2023)"
# ============================================================================
# API4:2023 - Unrestricted Resource Consumption
# ============================================================================
rate-limit-headers-documented:
description: API should document rate limiting headers
severity: warn
given: $.paths[*][get,post,put,patch,delete].responses[?(@property < '300')].headers
then:
function: schema
functionOptions:
schema:
type: object
anyOf:
- required: [X-RateLimit-Limit]
- required: [X-Rate-Limit-Limit]
- required: [RateLimit-Limit]
message: "Document rate limiting headers to communicate resource consumption limits (OWASP API4:2023 - Unrestricted Resource Consumption)"
pagination-parameters-present:
description: List operations should support pagination
severity: warn
given: $.paths[*].get
then:
- field: parameters
function: schema
functionOptions:
schema:
type: array
contains:
anyOf:
- properties:
name:
enum: [limit, per_page, page_size]
- properties:
name:
enum: [offset, page, cursor]
message: "List operations should support pagination (limit/offset or cursor) to prevent resource exhaustion (OWASP API4:2023)"
# ============================================================================
# API5:2023 - Broken Function Level Authorization
# ============================================================================
write-operations-require-security:
description: Write operations must have security requirements
severity: error
given: $.paths[*][post,put,patch,delete]
then:
- field: security
function: truthy
message: "Write operations must have security requirements to prevent unauthorized function access (OWASP API5:2023 - Broken Function Level Authorization)"
admin-paths-require-security:
description: Admin endpoints must have strict security
severity: error
given: $.paths[?(@property =~ /admin/i)][*]
then:
- field: security
function: truthy
message: "Admin endpoints require security requirements with appropriate scopes (OWASP API5:2023)"
# ============================================================================
# API7:2023 - Server Side Request Forgery
# ============================================================================
no-url-parameters:
description: Avoid URL parameters to prevent SSRF attacks
severity: warn
given: $.paths[*][*].parameters[?(@.in == 'query' || @.in == 'body')][?(@.name =~ /(url|uri|link|callback|redirect|webhook)/i)]
then:
function: truthy
message: "URL parameters can enable SSRF attacks - validate and whitelist destination URLs (OWASP API7:2023 - Server Side Request Forgery)"
# ============================================================================
# API8:2023 - Security Misconfiguration
# ============================================================================
servers-use-https:
description: All API servers must use HTTPS
severity: error
given: $.servers[*].url
then:
function: pattern
functionOptions:
match: "^https://"
message: "Server URLs must use HTTPS protocol for secure communication (OWASP API8:2023 - Security Misconfiguration)"
no-example-servers:
description: Replace example server URLs with actual endpoints
severity: error
given: $.servers[*].url
then:
function: pattern
functionOptions:
notMatch: "example\\.com"
message: "Replace example.com with actual production server URLs (OWASP API8:2023)"
security-headers-in-responses:
description: Document security headers in responses
severity: info
given: $.paths[*][*].responses[*].headers
then:
function: schema
functionOptions:
schema:
type: object
anyOf:
- required: [X-Content-Type-Options]
- required: [X-Frame-Options]
- required: [Strict-Transport-Security]
- required: [Content-Security-Policy]
message: "Consider documenting security headers (X-Content-Type-Options, X-Frame-Options, HSTS, CSP) (OWASP API8:2023)"
# ============================================================================
# API9:2023 - Improper Inventory Management
# ============================================================================
api-version-required:
description: API specification must include version
severity: error
given: $.info
then:
- field: version
function: truthy
message: "API version must be specified for proper inventory management (OWASP API9:2023 - Improper Inventory Management)"
semantic-versioning-format:
description: Use semantic versioning for API versions
severity: warn
given: $.info.version
then:
function: pattern
functionOptions:
match: "^\\d+\\.\\d+(\\.\\d+)?$"
message: "Use semantic versioning format (MAJOR.MINOR.PATCH) for API versions (OWASP API9:2023)"
contact-info-required:
description: API must include contact information
severity: warn
given: $.info
then:
- field: contact
function: truthy
message: "Include contact information for API support and security reporting (OWASP API9:2023)"
deprecated-endpoints-documented:
description: Deprecated endpoints must document migration path
severity: warn
given: $.paths[*][*][?(@.deprecated == true)]
then:
- field: description
function: pattern
functionOptions:
match: "(deprecate|migrate|alternative|replacement|use instead)"
message: "Deprecated endpoints must document migration path and timeline (OWASP API9:2023)"
# ============================================================================
# API10:2023 - Unsafe Consumption of APIs
# ============================================================================
validate-external-api-responses:
description: Document validation of external API responses
severity: info
given: $.paths[*][*].responses[*].content[*].schema
then:
- field: description
function: truthy
message: "Document schema validation for all API responses, especially from external APIs (OWASP API10:2023 - Unsafe Consumption of APIs)"
# ============================================================================
# Additional Security Best Practices
# ============================================================================
no-pii-in-query-parameters:
description: Prevent PII exposure in URL query parameters
severity: error
given: $.paths[*][*].parameters[?(@.in == 'query')].name
then:
function: pattern
functionOptions:
notMatch: "(?i)(ssn|social.?security|credit.?card|password|secret|token|api.?key|private|passport|driver.?license)"
message: "Query parameters must not contain PII or sensitive data - use request body with HTTPS instead"
consistent-error-response-format:
description: Error responses should follow consistent format
severity: warn
given: $.paths[*][*].responses[?(@property >= '400')].content.application/json.schema
then:
function: schema
functionOptions:
schema:
type: object
required: [error, message]
message: "Error responses should follow consistent format with 'error' and 'message' fields"
no-verbose-error-details:
description: 5xx errors should not expose internal details
severity: warn
given: $.paths[*][*].responses[?(@property >= '500')].content[*].schema.properties
then:
function: schema
functionOptions:
schema:
type: object
not:
anyOf:
- required: [stack_trace]
- required: [stackTrace]
- required: [debug_info]
message: "5xx error responses should not expose stack traces or internal details in production"

View File

@@ -0,0 +1,550 @@
# Reference Document Template
This file demonstrates how to structure detailed reference material that Claude loads on-demand.
**When to use this reference**: Include a clear statement about when Claude should consult this document.
For example: "Consult this reference when analyzing Python code for security vulnerabilities and needing detailed remediation patterns."
**Document purpose**: Briefly explain what this reference provides that's not in SKILL.md.
---
## Table of Contents
**For documents >100 lines, always include a table of contents** to help Claude navigate quickly.
- [When to Use References](#when-to-use-references)
- [Document Organization](#document-organization)
- [Detailed Technical Content](#detailed-technical-content)
- [Security Framework Mappings](#security-framework-mappings)
- [OWASP Top 10](#owasp-top-10)
- [CWE Mappings](#cwe-mappings)
- [MITRE ATT&CK](#mitre-attck)
- [Remediation Patterns](#remediation-patterns)
- [Advanced Configuration](#advanced-configuration)
- [Examples and Code Samples](#examples-and-code-samples)
---
## When to Use References
**Move content from SKILL.md to references/** when:
1. **Content exceeds 100 lines** - Keep SKILL.md concise
2. **Framework-specific details** - Detailed OWASP/CWE/MITRE mappings
3. **Advanced user content** - Deep technical details for expert users
4. **Lookup-oriented content** - Rule libraries, configuration matrices, comprehensive lists
5. **Language-specific patterns** - Separate files per language/framework
6. **Historical context** - Old patterns and deprecated approaches
**Keep in SKILL.md**:
- Core workflows (top 3-5 use cases)
- Decision points and branching logic
- Quick start guidance
- Essential security considerations
---
## Document Organization
### Structure for Long Documents
For references >100 lines:
```markdown
# Title
**When to use**: Clear trigger statement
**Purpose**: What this provides
## Table of Contents
- Links to all major sections
## Quick Reference
- Key facts or commands for fast lookup
## Detailed Content
- Comprehensive information organized logically
## Framework Mappings
- OWASP, CWE, MITRE ATT&CK references
## Examples
- Code samples and patterns
```
### Section Naming Conventions
- Use **imperative** or **declarative** headings
- ✅ "Detecting SQL Injection" not "How to detect SQL Injection"
- ✅ "Common Patterns" not "These are common patterns"
- Make headings **searchable** and **specific**
---
## Detailed Technical Content
This section demonstrates the type of detailed content that belongs in references rather than SKILL.md.
### Example: Comprehensive Vulnerability Detection
#### SQL Injection Detection Patterns
**Pattern 1: String Concatenation in Queries**
```python
# Vulnerable pattern
query = "SELECT * FROM users WHERE id = " + user_id
cursor.execute(query)
# Detection criteria:
# - SQL keyword (SELECT, INSERT, UPDATE, DELETE)
# - String concatenation operator (+, f-string)
# - Variable user input (request params, form data)
# Severity: HIGH
# CWE: CWE-89
# OWASP: A03:2021 - Injection
```
**Remediation**:
```python
# Fixed: Parameterized query
query = "SELECT * FROM users WHERE id = ?"
cursor.execute(query, (user_id,))
# OR using ORM
user = User.objects.get(id=user_id)
```
**Pattern 2: Unsafe String Formatting**
```python
# Vulnerable patterns
query = f"SELECT * FROM users WHERE name = '{username}'"
query = "SELECT * FROM users WHERE name = '%s'" % username
query = "SELECT * FROM users WHERE name = '{}'".format(username)
# All three patterns are vulnerable to SQL injection
```
#### Cross-Site Scripting (XSS) Detection
**Pattern 1: Unescaped Output in Templates**
```javascript
// Vulnerable: Direct HTML injection
element.innerHTML = userInput;
document.write(userInput);
// Vulnerable: React dangerouslySetInnerHTML
<div dangerouslySetInnerHTML={{__html: userComment}} />
// Detection criteria:
# - Direct DOM manipulation (innerHTML, document.write)
# - React dangerouslySetInnerHTML with user data
# - Template engines with autoescaping disabled
// Severity: HIGH
// CWE: CWE-79
// OWASP: A03:2021 - Injection
```
**Remediation**:
```javascript
// Fixed: Escaped output
element.textContent = userInput; // Auto-escapes
// Fixed: Sanitization library
import DOMPurify from 'dompurify';
const clean = DOMPurify.sanitize(userComment);
<div dangerouslySetInnerHTML={{__html: clean}} />
```
---
## Security Framework Mappings
This section provides comprehensive security framework mappings for findings.
### OWASP Top 10
Map security findings to OWASP Top 10 (2021) categories:
| Category | Title | Common Vulnerabilities |
|----------|-------|----------------------|
| **A01:2021** | Broken Access Control | Authorization bypass, privilege escalation, IDOR |
| **A02:2021** | Cryptographic Failures | Weak crypto, plaintext storage, insecure TLS |
| **A03:2021** | Injection | SQL injection, XSS, command injection, LDAP injection |
| **A04:2021** | Insecure Design | Missing security controls, threat modeling gaps |
| **A05:2021** | Security Misconfiguration | Default configs, verbose errors, unnecessary features |
| **A06:2021** | Vulnerable Components | Outdated libraries, unpatched dependencies |
| **A07:2021** | Auth & Session Failures | Weak passwords, session fixation, missing MFA |
| **A08:2021** | Software & Data Integrity | Unsigned updates, insecure CI/CD, deserialization |
| **A09:2021** | Logging & Monitoring Failures | Insufficient logging, no alerting, log injection |
| **A10:2021** | SSRF | Server-side request forgery, unvalidated redirects |
**Usage**: When reporting findings, map to primary OWASP category and reference the identifier (e.g., "A03:2021 - Injection").
### CWE Mappings
Map to relevant Common Weakness Enumeration categories for precise vulnerability classification:
#### Injection Vulnerabilities
- **CWE-78**: OS Command Injection
- **CWE-79**: Cross-site Scripting (XSS)
- **CWE-89**: SQL Injection
- **CWE-90**: LDAP Injection
- **CWE-91**: XML Injection
- **CWE-94**: Code Injection
#### Authentication & Authorization
- **CWE-287**: Improper Authentication
- **CWE-288**: Authentication Bypass Using Alternate Path
- **CWE-290**: Authentication Bypass by Spoofing
- **CWE-294**: Authentication Bypass by Capture-replay
- **CWE-306**: Missing Authentication for Critical Function
- **CWE-307**: Improper Restriction of Excessive Authentication Attempts
- **CWE-352**: Cross-Site Request Forgery (CSRF)
#### Cryptographic Issues
- **CWE-256**: Plaintext Storage of Password
- **CWE-259**: Use of Hard-coded Password
- **CWE-261**: Weak Encoding for Password
- **CWE-321**: Use of Hard-coded Cryptographic Key
- **CWE-326**: Inadequate Encryption Strength
- **CWE-327**: Use of Broken or Risky Cryptographic Algorithm
- **CWE-329**: Not Using a Random IV with CBC Mode
- **CWE-798**: Use of Hard-coded Credentials
#### Input Validation
- **CWE-20**: Improper Input Validation
- **CWE-73**: External Control of File Name or Path
- **CWE-434**: Unrestricted Upload of File with Dangerous Type
- **CWE-601**: URL Redirection to Untrusted Site
#### Sensitive Data Exposure
- **CWE-200**: Information Exposure
- **CWE-209**: Information Exposure Through Error Message
- **CWE-312**: Cleartext Storage of Sensitive Information
- **CWE-319**: Cleartext Transmission of Sensitive Information
- **CWE-532**: Information Exposure Through Log Files
**Usage**: Include CWE identifier in all vulnerability reports for standardized classification.
### MITRE ATT&CK
Reference relevant tactics and techniques for threat context:
#### Initial Access (TA0001)
- **T1190**: Exploit Public-Facing Application
- **T1133**: External Remote Services
- **T1078**: Valid Accounts
#### Execution (TA0002)
- **T1059**: Command and Scripting Interpreter
- **T1203**: Exploitation for Client Execution
#### Persistence (TA0003)
- **T1098**: Account Manipulation
- **T1136**: Create Account
- **T1505**: Server Software Component
#### Privilege Escalation (TA0004)
- **T1068**: Exploitation for Privilege Escalation
- **T1548**: Abuse Elevation Control Mechanism
#### Defense Evasion (TA0005)
- **T1027**: Obfuscated Files or Information
- **T1140**: Deobfuscate/Decode Files or Information
- **T1562**: Impair Defenses
#### Credential Access (TA0006)
- **T1110**: Brute Force
- **T1555**: Credentials from Password Stores
- **T1552**: Unsecured Credentials
#### Discovery (TA0007)
- **T1083**: File and Directory Discovery
- **T1046**: Network Service Scanning
#### Collection (TA0009)
- **T1005**: Data from Local System
- **T1114**: Email Collection
#### Exfiltration (TA0010)
- **T1041**: Exfiltration Over C2 Channel
- **T1567**: Exfiltration Over Web Service
**Usage**: When identifying vulnerabilities, consider which ATT&CK techniques an attacker could use to exploit them.
---
## Remediation Patterns
This section provides specific remediation guidance for common vulnerability types.
### SQL Injection Remediation
**Step 1: Identify vulnerable queries**
- Search for string concatenation in SQL queries
- Check for f-strings or format() with SQL keywords
- Review all database interaction code
**Step 2: Apply parameterized queries**
```python
# Python with sqlite3
cursor.execute("SELECT * FROM users WHERE id = ?", (user_id,))
# Python with psycopg2 (PostgreSQL)
cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
# Python with SQLAlchemy (ORM)
from sqlalchemy import text
result = session.execute(text("SELECT * FROM users WHERE id = :id"), {"id": user_id})
```
**Step 3: Validate and sanitize input** (defense in depth)
```python
import re
# Validate input format
if not re.match(r'^\d+$', user_id):
raise ValueError("Invalid user ID format")
# Use ORM query builders
user = User.query.filter_by(id=user_id).first()
```
**Step 4: Implement least privilege**
- Database user should have minimum required permissions
- Use read-only accounts for SELECT operations
- Never use admin/root accounts for application queries
### XSS Remediation
**Step 1: Enable auto-escaping**
- Most modern frameworks escape by default
- Ensure auto-escaping is not disabled
**Step 2: Use framework-specific safe methods**
```javascript
// React: Use JSX (auto-escapes)
<div>{userInput}</div>
// Vue: Use template syntax (auto-escapes)
<div>{{ userInput }}</div>
// Angular: Use property binding (auto-escapes)
<div [textContent]="userInput"></div>
```
**Step 3: Sanitize when HTML is required**
```javascript
import DOMPurify from 'dompurify';
// Sanitize HTML content
const clean = DOMPurify.sanitize(userHTML, {
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'p'],
ALLOWED_ATTR: []
});
```
**Step 4: Content Security Policy (CSP)**
```html
<!-- Add CSP header -->
Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-{random}'
```
---
## Advanced Configuration
This section contains detailed configuration options and tuning parameters.
### Example: SAST Tool Configuration
```yaml
# Advanced security scanner configuration
scanner:
# Severity threshold
severity_threshold: MEDIUM
# Rule configuration
rules:
enabled:
- sql-injection
- xss
- hardcoded-secrets
disabled:
- informational-only
# False positive reduction
confidence_threshold: HIGH
exclude_patterns:
- "*/test/*"
- "*/tests/*"
- "*/node_modules/*"
- "*.test.js"
- "*.spec.ts"
# Performance tuning
max_file_size_kb: 2048
timeout_seconds: 300
parallel_jobs: 4
# Output configuration
output_format: json
include_code_snippets: true
max_snippet_lines: 10
```
---
## Examples and Code Samples
This section provides comprehensive code examples for various scenarios.
### Example 1: Secure API Authentication
```python
# Secure API key handling
import os
from functools import wraps
from flask import Flask, request, jsonify
app = Flask(__name__)
# Load API key from environment (never hardcode)
VALID_API_KEY = os.environ.get('API_KEY')
if not VALID_API_KEY:
raise ValueError("API_KEY environment variable not set")
def require_api_key(f):
@wraps(f)
def decorated_function(*args, **kwargs):
api_key = request.headers.get('X-API-Key')
if not api_key:
return jsonify({'error': 'API key required'}), 401
# Constant-time comparison to prevent timing attacks
import hmac
if not hmac.compare_digest(api_key, VALID_API_KEY):
return jsonify({'error': 'Invalid API key'}), 403
return f(*args, **kwargs)
return decorated_function
@app.route('/api/secure-endpoint')
@require_api_key
def secure_endpoint():
return jsonify({'message': 'Access granted'})
```
### Example 2: Secure Password Hashing
```python
# Secure password storage with bcrypt
import bcrypt
def hash_password(password: str) -> str:
"""Hash a password using bcrypt."""
# Generate salt and hash password
salt = bcrypt.gensalt(rounds=12) # Cost factor: 12 (industry standard)
hashed = bcrypt.hashpw(password.encode('utf-8'), salt)
return hashed.decode('utf-8')
def verify_password(password: str, hashed: str) -> bool:
"""Verify a password against a hash."""
return bcrypt.checkpw(
password.encode('utf-8'),
hashed.encode('utf-8')
)
# Usage
stored_hash = hash_password("user_password")
is_valid = verify_password("user_password", stored_hash) # True
```
### Example 3: Secure File Upload
```python
# Secure file upload with validation
import os
import magic
from werkzeug.utils import secure_filename
ALLOWED_EXTENSIONS = {'pdf', 'png', 'jpg', 'jpeg'}
ALLOWED_MIME_TYPES = {
'application/pdf',
'image/png',
'image/jpeg'
}
MAX_FILE_SIZE = 5 * 1024 * 1024 # 5 MB
def is_allowed_file(filename: str, file_content: bytes) -> bool:
"""Validate file extension and MIME type."""
# Check extension
if '.' not in filename:
return False
ext = filename.rsplit('.', 1)[1].lower()
if ext not in ALLOWED_EXTENSIONS:
return False
# Check MIME type (prevent extension spoofing)
mime = magic.from_buffer(file_content, mime=True)
if mime not in ALLOWED_MIME_TYPES:
return False
return True
def handle_upload(file):
"""Securely handle file upload."""
# Check file size
file.seek(0, os.SEEK_END)
size = file.tell()
file.seek(0)
if size > MAX_FILE_SIZE:
raise ValueError("File too large")
# Read content for validation
content = file.read()
file.seek(0)
# Validate file type
if not is_allowed_file(file.filename, content):
raise ValueError("Invalid file type")
# Sanitize filename
filename = secure_filename(file.filename)
# Generate unique filename to prevent overwrite attacks
import uuid
unique_filename = f"{uuid.uuid4()}_{filename}"
# Save to secure location (outside web root)
upload_path = os.path.join('/secure/uploads', unique_filename)
file.save(upload_path)
return unique_filename
```
---
## Best Practices for Reference Documents
1. **Start with "When to use"** - Help Claude know when to load this reference
2. **Include table of contents** - For documents >100 lines
3. **Use concrete examples** - Code samples with vulnerable and fixed versions
4. **Map to frameworks** - OWASP, CWE, MITRE ATT&CK for context
5. **Provide remediation** - Don't just identify issues, show how to fix them
6. **Organize logically** - Group related content, use clear headings
7. **Keep examples current** - Use modern patterns and current framework versions
8. **Be concise** - Even in references, challenge every sentence

View File

@@ -0,0 +1,253 @@
# Workflow Checklist Template
This template demonstrates workflow patterns for security operations. Copy and adapt these checklists to your specific skill needs.
## Pattern 1: Sequential Workflow Checklist
Use this pattern for operations that must be completed in order, step-by-step.
### Security Assessment Workflow
Progress:
[ ] 1. Identify application entry points and attack surface
[ ] 2. Map authentication and authorization flows
[ ] 3. Identify data flows and sensitive data handling
[ ] 4. Review existing security controls
[ ] 5. Document findings with framework references (OWASP, CWE)
[ ] 6. Prioritize findings by severity (CVSS scores)
[ ] 7. Generate report with remediation recommendations
Work through each step systematically. Check off completed items.
---
## Pattern 2: Conditional Workflow
Use this pattern when the workflow branches based on findings or conditions.
### Vulnerability Remediation Workflow
1. Identify vulnerability type
- If SQL Injection → See [sql-injection-remediation.md](sql-injection-remediation.md)
- If XSS (Cross-Site Scripting) → See [xss-remediation.md](xss-remediation.md)
- If Authentication flaw → See [auth-remediation.md](auth-remediation.md)
- If Authorization flaw → See [authz-remediation.md](authz-remediation.md)
- If Cryptographic issue → See [crypto-remediation.md](crypto-remediation.md)
2. Assess severity using CVSS calculator
- If CVSS >= 9.0 → Priority: Critical (immediate action)
- If CVSS 7.0-8.9 → Priority: High (action within 24h)
- If CVSS 4.0-6.9 → Priority: Medium (action within 1 week)
- If CVSS < 4.0 → Priority: Low (action within 30 days)
3. Apply appropriate remediation pattern
4. Validate fix with security testing
5. Document changes and update security documentation
---
## Pattern 3: Iterative Workflow
Use this pattern for operations that repeat across multiple targets or items.
### Code Security Review Workflow
For each file in the review scope:
1. Identify security-sensitive operations (auth, data access, crypto, input handling)
2. Check against secure coding patterns for the language
3. Flag potential vulnerabilities with severity rating
4. Map findings to CWE and OWASP categories
5. Suggest specific remediation approaches
6. Document finding with code location and fix priority
Continue until all files in scope have been reviewed.
---
## Pattern 4: Feedback Loop Workflow
Use this pattern when validation and iteration are required.
### Secure Configuration Generation Workflow
1. Generate initial security configuration based on requirements
2. Run validation script: `./scripts/validate_config.py config.yaml`
3. Review validation output:
- Note all errors (must fix)
- Note all warnings (should fix)
- Note all info items (consider)
4. Fix identified issues in configuration
5. Repeat steps 2-4 until validation passes with zero errors
6. Review warnings and determine if they should be addressed
7. Apply configuration once validation is clean
**Validation Loop**: Run validator → Fix errors → Repeat until clean
---
## Pattern 5: Parallel Analysis Workflow
Use this pattern when multiple independent analyses can run concurrently.
### Comprehensive Security Scan Workflow
Run these scans in parallel:
**Static Analysis**:
[ ] 1a. Run SAST scan (Semgrep/Bandit)
[ ] 1b. Run dependency vulnerability scan (Safety/npm audit)
[ ] 1c. Run secrets detection (Gitleaks/TruffleHog)
[ ] 1d. Run license compliance check
**Dynamic Analysis**:
[ ] 2a. Run DAST scan (ZAP/Burp)
[ ] 2b. Run API security testing
[ ] 2c. Run authentication/authorization testing
**Infrastructure Analysis**:
[ ] 3a. Run infrastructure-as-code scan (Checkov/tfsec)
[ ] 3b. Run container image scan (Trivy/Grype)
[ ] 3c. Run configuration review
**Consolidation**:
[ ] 4. Aggregate all findings
[ ] 5. Deduplicate and correlate findings
[ ] 6. Prioritize by risk (CVSS + exploitability + business impact)
[ ] 7. Generate unified security report
---
## Pattern 6: Research and Documentation Workflow
Use this pattern for security research and documentation tasks.
### Threat Modeling Workflow
Research Progress:
[ ] 1. Identify system components and boundaries
[ ] 2. Map data flows between components
[ ] 3. Identify trust boundaries
[ ] 4. Enumerate assets (data, services, credentials)
[ ] 5. Apply STRIDE framework to each component:
- Spoofing threats
- Tampering threats
- Repudiation threats
- Information disclosure threats
- Denial of service threats
- Elevation of privilege threats
[ ] 6. Map threats to MITRE ATT&CK techniques
[ ] 7. Identify existing mitigations
[ ] 8. Document residual risks
[ ] 9. Recommend additional security controls
[ ] 10. Generate threat model document
Work through each step systematically. Check off completed items.
---
## Pattern 7: Compliance Validation Workflow
Use this pattern for compliance checks against security standards.
### Security Compliance Audit Workflow
**SOC 2 Controls Review**:
[ ] 1. Review access control policies (CC6.1, CC6.2, CC6.3)
[ ] 2. Verify logical access controls implementation (CC6.1)
[ ] 3. Review authentication mechanisms (CC6.1)
[ ] 4. Verify encryption implementation (CC6.1, CC6.7)
[ ] 5. Review audit logging configuration (CC7.2)
[ ] 6. Verify security monitoring (CC7.2, CC7.3)
[ ] 7. Review incident response procedures (CC7.3, CC7.4)
[ ] 8. Verify backup and recovery processes (A1.2, A1.3)
**Evidence Collection**:
[ ] 9. Collect policy documents
[ ] 10. Collect configuration screenshots
[ ] 11. Collect audit logs
[ ] 12. Document control gaps
[ ] 13. Generate compliance report
---
## Pattern 8: Incident Response Workflow
Use this pattern for security incident handling.
### Security Incident Response Workflow
**Detection and Analysis**:
[ ] 1. Confirm security incident (rule out false positive)
[ ] 2. Determine incident severity (SEV1/2/3/4)
[ ] 3. Identify affected systems and data
[ ] 4. Preserve evidence (logs, memory dumps, network captures)
**Containment**:
[ ] 5. Isolate affected systems (network segmentation)
[ ] 6. Disable compromised accounts
[ ] 7. Block malicious indicators (IPs, domains, hashes)
[ ] 8. Implement temporary compensating controls
**Eradication**:
[ ] 9. Identify root cause
[ ] 10. Remove malicious artifacts (malware, backdoors, webshells)
[ ] 11. Patch vulnerabilities exploited
[ ] 12. Reset compromised credentials
**Recovery**:
[ ] 13. Restore systems from clean backups (if needed)
[ ] 14. Re-enable systems with monitoring
[ ] 15. Verify system integrity
[ ] 16. Resume normal operations
**Post-Incident**:
[ ] 17. Document incident timeline
[ ] 18. Identify lessons learned
[ ] 19. Update security controls to prevent recurrence
[ ] 20. Update incident response procedures
[ ] 21. Communicate with stakeholders
---
## Usage Guidelines
### When to Use Workflow Checklists
**Use checklists for**:
- Complex multi-step operations
- Operations requiring specific order
- Security assessments and audits
- Incident response procedures
- Compliance validation tasks
**Don't use checklists for**:
- Simple single-step operations
- Highly dynamic exploratory work
- Operations that vary significantly each time
### Adapting This Template
1. **Copy relevant pattern** to your skill's SKILL.md or create new reference file
2. **Customize steps** to match your specific security tool or process
3. **Add framework references** (OWASP, CWE, NIST) where applicable
4. **Include tool-specific commands** for automation
5. **Add decision points** where manual judgment is required
### Checklist Best Practices
- **Be specific**: "Run semgrep --config=auto ." not "Scan the code"
- **Include success criteria**: "Validation passes with 0 errors"
- **Reference standards**: Link to OWASP, CWE, NIST where relevant
- **Show progress**: Checkbox format helps track completion
- **Provide escape hatches**: "If validation fails, see troubleshooting.md"
### Integration with Feedback Loops
Combine checklists with validation scripts for maximum effectiveness:
1. Create checklist for the workflow
2. Provide validation script that checks quality
3. Include "run validator" step in checklist
4. Loop: Complete step → Validate → Fix issues → Re-validate
This pattern dramatically improves output quality through systematic validation.

View File

@@ -0,0 +1,553 @@
# Spectral Custom Rules Development Guide
This guide covers creating custom security rules for Spectral to enforce organization-specific API security standards.
## Table of Contents
- [Rule Structure](#rule-structure)
- [JSONPath Expressions](#jsonpath-expressions)
- [Built-in Functions](#built-in-functions)
- [Security Rule Examples](#security-rule-examples)
- [Testing Custom Rules](#testing-custom-rules)
- [Best Practices](#best-practices)
## Rule Structure
Every Spectral rule consists of:
```yaml
rules:
rule-name:
description: Human-readable description
severity: error|warn|info|hint
given: JSONPath expression targeting specific parts of spec
then:
- field: property to check (optional)
function: validation function
functionOptions: function-specific options
message: Error message shown when rule fails
```
### Severity Levels
- **error**: Critical security issues that must be fixed
- **warn**: Important security recommendations
- **info**: Best practices and suggestions
- **hint**: Style guide and documentation improvements
## JSONPath Expressions
### Basic Path Selection
```yaml
# Target all paths
given: $.paths[*]
# Target all GET operations
given: $.paths[*].get
# Target all HTTP methods
given: $.paths[*][get,post,put,patch,delete]
# Target security schemes
given: $.components.securitySchemes[*]
# Target all schemas
given: $.components.schemas[*]
```
### Advanced Filters
```yaml
# Filter by property value
given: $.paths[*][?(@.security)]
# Filter objects by type
given: $.components.schemas[?(@.type == 'object')]
# Filter parameters by location
given: $.paths[*][*].parameters[?(@.in == 'query')]
# Regular expression matching
given: $.paths[*][*].parameters[?(@.name =~ /^(id|.*_id)$/i)]
# Nested property access
given: $.paths[*][*].responses[?(@property >= 400)]
```
## Built-in Functions
### truthy / falsy
Check if field exists or doesn't exist:
```yaml
# Require field to exist
then:
- field: security
function: truthy
# Require field to not exist
then:
- field: additionalProperties
function: falsy
```
### pattern
Match string against regex pattern:
```yaml
# Match HTTPS URLs
then:
function: pattern
functionOptions:
match: "^https://"
# Ensure no sensitive terms
then:
function: pattern
functionOptions:
notMatch: "(password|secret|api[_-]?key)"
```
### enumeration
Restrict to specific values:
```yaml
# Require specific auth types
then:
field: type
function: enumeration
functionOptions:
values: [apiKey, oauth2, openIdConnect]
```
### length
Validate string/array length:
```yaml
# Minimum description length
then:
field: description
function: length
functionOptions:
min: 10
max: 500
```
### schema
Validate against JSON Schema:
```yaml
# Require specific object structure
then:
function: schema
functionOptions:
schema:
type: object
required: [error, message]
properties:
error:
type: string
message:
type: string
```
### alphabetical
Ensure alphabetical ordering:
```yaml
# Require alphabetically sorted tags
then:
field: tags
function: alphabetical
```
## Security Rule Examples
### Prevent PII in URL Parameters
```yaml
no-pii-in-query-params:
description: Query parameters must not contain PII
severity: error
given: $.paths[*][*].parameters[?(@.in == 'query')].name
then:
function: pattern
functionOptions:
notMatch: "(?i)(ssn|social.?security|credit.?card|password|passport|driver.?license|tax.?id|national.?id)"
message: "Query parameter names suggest PII - use request body instead"
```
### Require API Key for Authentication
```yaml
require-api-key-security:
description: APIs must use API key authentication
severity: error
given: $.components.securitySchemes
then:
function: schema
functionOptions:
schema:
type: object
minProperties: 1
patternProperties:
".*":
anyOf:
- properties:
type:
const: apiKey
- properties:
type:
const: oauth2
- properties:
type:
const: openIdConnect
message: "API must define apiKey, OAuth2, or OpenID Connect security"
```
### Enforce Rate Limiting Headers
```yaml
rate-limit-headers-present:
description: Responses should include rate limit headers
severity: warn
given: $.paths[*][get,post,put,patch,delete].responses[?(@property == '200' || @property == '201')].headers
then:
function: schema
functionOptions:
schema:
type: object
anyOf:
- required: [X-RateLimit-Limit]
- required: [X-Rate-Limit-Limit]
message: "Include rate limit headers (X-RateLimit-Limit, X-RateLimit-Remaining) in success responses"
```
### Detect Missing Authorization for Sensitive Operations
```yaml
sensitive-operations-require-security:
description: Sensitive operations must have security requirements
severity: error
given: $.paths[*][post,put,patch,delete]
then:
- field: security
function: truthy
message: "Write operations must have security requirements defined"
```
### Prevent Verbose Error Messages
```yaml
no-verbose-error-responses:
description: Error responses should not expose internal details
severity: warn
given: $.paths[*][*].responses[?(@property >= 500)].content.application/json.schema.properties
then:
function: schema
functionOptions:
schema:
type: object
not:
anyOf:
- required: [stack_trace]
- required: [stackTrace]
- required: [debug_info]
- required: [internal_message]
message: "5xx error responses should not expose stack traces or internal details"
```
### Require Audit Fields in Schemas
```yaml
require-audit-fields:
description: Data models should include audit fields
severity: info
given: $.components.schemas[?(@.type == 'object' && @.properties)]
then:
function: schema
functionOptions:
schema:
type: object
properties:
properties:
type: object
anyOf:
- required: [created_at, updated_at]
- required: [createdAt, updatedAt]
message: "Consider adding audit fields (created_at, updated_at) to data models"
```
### Detect Insecure Content Types
```yaml
no-insecure-content-types:
description: Avoid insecure content types
severity: warn
given: $.paths[*][*].requestBody.content
then:
function: schema
functionOptions:
schema:
type: object
not:
required: [text/html, text/xml, application/x-www-form-urlencoded]
message: "Prefer application/json over HTML, XML, or form-encoded content types"
```
### Validate JWT Security Configuration
```yaml
jwt-proper-configuration:
description: JWT bearer authentication should be properly configured
severity: error
given: $.components.securitySchemes[?(@.type == 'http' && @.scheme == 'bearer')]
then:
- field: bearerFormat
function: pattern
functionOptions:
match: "^JWT$"
message: "Bearer authentication should specify 'JWT' as bearerFormat"
```
### Require CORS Documentation
```yaml
cors-options-documented:
description: CORS preflight endpoints should be documented
severity: warn
given: $.paths[*]
then:
function: schema
functionOptions:
schema:
type: object
if:
properties:
get:
type: object
then:
properties:
options:
type: object
required: [responses]
message: "Document OPTIONS method for CORS preflight requests"
```
### Prevent Numeric IDs in URLs
```yaml
prefer-uuid-over-numeric-ids:
description: Use UUIDs instead of numeric IDs to prevent enumeration
severity: info
given: $.paths.*~
then:
function: pattern
functionOptions:
notMatch: "\\{id\\}|\\{.*_id\\}"
message: "Consider using UUIDs instead of numeric IDs to prevent enumeration attacks"
```
## Testing Custom Rules
### Create Test Specifications
```yaml
# test-specs/valid-auth.yaml
openapi: 3.0.0
info:
title: Valid API
version: 1.0.0
components:
securitySchemes:
apiKey:
type: apiKey
in: header
name: X-API-Key
security:
- apiKey: []
```
```yaml
# test-specs/invalid-auth.yaml
openapi: 3.0.0
info:
title: Invalid API
version: 1.0.0
components:
securitySchemes:
basicAuth:
type: http
scheme: basic
security:
- basicAuth: []
```
### Test Rules
```bash
# Test custom ruleset
spectral lint test-specs/valid-auth.yaml --ruleset .spectral-custom.yaml
# Expected: No errors
spectral lint test-specs/invalid-auth.yaml --ruleset .spectral-custom.yaml
# Expected: Error about HTTP Basic auth
```
### Automated Testing Script
```bash
#!/bin/bash
# test-rules.sh - Test custom Spectral rules
RULESET=".spectral-custom.yaml"
TEST_DIR="test-specs"
PASS=0
FAIL=0
for spec in "$TEST_DIR"/*.yaml; do
echo "Testing: $spec"
if spectral lint "$spec" --ruleset "$RULESET" > /dev/null 2>&1; then
if [[ "$spec" == *"valid"* ]]; then
echo " ✓ PASS (correctly validated)"
((PASS++))
else
echo " ✗ FAIL (should have detected issues)"
((FAIL++))
fi
else
if [[ "$spec" == *"invalid"* ]]; then
echo " ✓ PASS (correctly detected issues)"
((PASS++))
else
echo " ✗ FAIL (false positive)"
((FAIL++))
fi
fi
done
echo ""
echo "Results: $PASS passed, $FAIL failed"
```
## Best Practices
### 1. Start with Built-in Rules
Extend existing rulesets instead of starting from scratch:
```yaml
extends: ["spectral:oas", "spectral:asyncapi"]
rules:
# Add custom rules here
custom-security-rule:
# ...
```
### 2. Use Descriptive Names
Rule names should clearly indicate what they check:
```yaml
# Good
no-pii-in-query-params:
require-https-servers:
jwt-bearer-format-required:
# Bad
check-params:
security-rule-1:
validate-auth:
```
### 3. Provide Actionable Messages
```yaml
# Good
message: "Query parameters must not contain PII (ssn, credit_card) - use request body instead"
# Bad
message: "Invalid parameter"
```
### 4. Choose Appropriate Severity
```yaml
# error - Must fix (security vulnerabilities)
severity: error
# warn - Should fix (security best practices)
severity: warn
# info - Consider fixing (recommendations)
severity: info
# hint - Nice to have (style guide)
severity: hint
```
### 5. Document Rule Rationale
```yaml
rules:
no-numeric-ids:
description: |
Use UUIDs instead of auto-incrementing numeric IDs in URLs to prevent
enumeration attacks where attackers can guess valid IDs sequentially.
This follows OWASP API Security best practices for API1:2023.
severity: warn
# ...
```
### 6. Use Rule Overrides for Exceptions
```yaml
# Allow specific paths to violate rules
overrides:
- files: ["**/internal-api.yaml"]
rules:
require-https-servers: off
- files: ["**/admin-api.yaml"]
rules:
no-http-basic-auth: warn # Downgrade to warning
```
### 7. Organize Rules by Category
```yaml
# .spectral.yaml - Main ruleset
extends:
- .spectral-auth.yaml # Authentication rules
- .spectral-authz.yaml # Authorization rules
- .spectral-data.yaml # Data protection rules
- .spectral-owasp.yaml # OWASP mappings
```
### 8. Version Control Your Rulesets
```bash
# Track ruleset evolution
git log -p .spectral.yaml
# Tag stable ruleset versions
git tag -a ruleset-v1.0 -m "Production-ready security ruleset"
```
## Additional Resources
- [Spectral Rulesets Documentation](https://docs.stoplight.io/docs/spectral/docs/getting-started/rulesets.md)
- [JSONPath Online Evaluator](https://jsonpath.com/)
- [Custom Functions Guide](./custom_functions.md)
- [OWASP API Security Mappings](./owasp_api_mappings.md)

View File

@@ -0,0 +1,472 @@
# OWASP API Security Top 10 2023 - Spectral Rule Mappings
This reference provides comprehensive Spectral rule mappings to OWASP API Security Top 10 2023, including custom rule examples for detecting each category of vulnerability.
## Table of Contents
- [API1:2023 - Broken Object Level Authorization](#api12023---broken-object-level-authorization)
- [API2:2023 - Broken Authentication](#api22023---broken-authentication)
- [API3:2023 - Broken Object Property Level Authorization](#api32023---broken-object-property-level-authorization)
- [API4:2023 - Unrestricted Resource Consumption](#api42023---unrestricted-resource-consumption)
- [API5:2023 - Broken Function Level Authorization](#api52023---broken-function-level-authorization)
- [API6:2023 - Unrestricted Access to Sensitive Business Flows](#api62023---unrestricted-access-to-sensitive-business-flows)
- [API7:2023 - Server Side Request Forgery](#api72023---server-side-request-forgery)
- [API8:2023 - Security Misconfiguration](#api82023---security-misconfiguration)
- [API9:2023 - Improper Inventory Management](#api92023---improper-inventory-management)
- [API10:2023 - Unsafe Consumption of APIs](#api102023---unsafe-consumption-of-apis)
---
## API1:2023 - Broken Object Level Authorization
**Description**: APIs tend to expose endpoints that handle object identifiers, creating a wide attack surface Level Access Control issue. Object level authorization checks should be considered in every function that accesses a data source using an input from the user.
### Spectral Rules
```yaml
# .spectral-api1.yaml
rules:
# Require security on all operations
operation-security-defined:
description: All operations must have security requirements (OWASP API1)
severity: error
given: $.paths[*][get,post,put,patch,delete]
then:
- field: security
function: truthy
message: "Operations must define security requirements to prevent unauthorized object access (OWASP API1:2023)"
# Detect ID parameters without authorization checks
id-parameter-requires-security:
description: Operations with ID parameters must have security defined
severity: error
given: $.paths[*][*].parameters[?(@.name =~ /^(id|.*[_-]id)$/i)]
then:
function: falsy
message: "Path contains ID parameter - ensure operation has security requirements (OWASP API1:2023)"
# Require authorization scopes for CRUD operations
crud-requires-authorization-scope:
description: CRUD operations should specify authorization scopes
severity: warn
given: $.paths[*][get,post,put,patch,delete].security[*]
then:
function: schema
functionOptions:
schema:
type: object
minProperties: 1
message: "CRUD operations should specify authorization scopes (OWASP API1:2023)"
```
### Remediation
- Implement object-level authorization checks in API specification security requirements
- Define per-operation security schemes with appropriate scopes
- Document which user roles can access which objects
- Consider using OAuth 2.0 with fine-grained scopes
---
## API2:2023 - Broken Authentication
**Description**: Authentication mechanisms are often implemented incorrectly, allowing attackers to compromise authentication tokens or exploit implementation flaws to assume other users' identities.
### Spectral Rules
```yaml
# .spectral-api2.yaml
rules:
# Require security schemes definition
security-schemes-required:
description: API must define security schemes (OWASP API2)
severity: error
given: $.components
then:
- field: securitySchemes
function: truthy
message: "API must define security schemes to prevent authentication bypass (OWASP API2:2023)"
# Prohibit HTTP Basic authentication
no-http-basic-auth:
description: HTTP Basic auth is insecure for APIs
severity: error
given: $.components.securitySchemes[*]
then:
- field: scheme
function: pattern
functionOptions:
notMatch: "^basic$"
message: "HTTP Basic authentication transmits credentials in plain text (OWASP API2:2023)"
# Require bearer token format specification
bearer-format-required:
description: Bearer authentication should specify token format (JWT recommended)
severity: warn
given: $.components.securitySchemes[?(@.type == 'http' && @.scheme == 'bearer')]
then:
- field: bearerFormat
function: truthy
message: "Bearer authentication should specify token format, preferably JWT (OWASP API2:2023)"
# Require OAuth2 flow for authentication
oauth2-recommended:
description: OAuth2 provides secure authentication flows
severity: info
given: $.components.securitySchemes[*]
then:
- field: type
function: enumeration
functionOptions:
values: [oauth2, openIdConnect, http]
message: "Consider using OAuth2 or OpenID Connect for robust authentication (OWASP API2:2023)"
```
### Remediation
- Use OAuth 2.0 or OpenID Connect for authentication
- Implement JWT with proper expiration and signature validation
- Avoid HTTP Basic authentication for production APIs
- Document authentication flows and token refresh mechanisms
---
## API3:2023 - Broken Object Property Level Authorization
**Description**: This category combines API3:2019 Excessive Data Exposure and API6:2019 Mass Assignment, focusing on the root cause: the lack of or improper authorization validation at the object property level.
### Spectral Rules
```yaml
# .spectral-api3.yaml
rules:
# Prohibit additionalProperties for security
no-additional-properties:
description: Prevent mass assignment by disabling additionalProperties
severity: warn
given: $.components.schemas[*]
then:
- field: additionalProperties
function: falsy
message: "Set additionalProperties to false to prevent mass assignment vulnerabilities (OWASP API3:2023)"
# Require explicit property definitions
schema-properties-required:
description: Schemas should explicitly define all properties
severity: warn
given: $.components.schemas[?(@.type == 'object')]
then:
- field: properties
function: truthy
message: "Explicitly define all object properties to control data exposure (OWASP API3:2023)"
# Warn on write-only properties
detect-write-only-properties:
description: Document write-only properties to prevent data exposure
severity: info
given: $.components.schemas[*].properties[*]
then:
- field: writeOnly
function: truthy
message: "Ensure write-only properties are properly handled (OWASP API3:2023)"
# Require read-only for sensitive computed fields
computed-fields-read-only:
description: Computed fields should be marked as readOnly
severity: warn
given: $.components.schemas[*].properties[?(@.description =~ /calculated|computed|derived/i)]
then:
- field: readOnly
function: truthy
message: "Mark computed/calculated fields as readOnly (OWASP API3:2023)"
```
### Remediation
- Set `additionalProperties: false` in schemas to prevent mass assignment
- Use `readOnly` for properties that shouldn't be modified by clients
- Use `writeOnly` for sensitive input properties (passwords, tokens)
- Document which properties are accessible to which user roles
---
## API4:2023 - Unrestricted Resource Consumption
**Description**: Satisfying API requests requires resources such as network bandwidth, CPU, memory, and storage. Sometimes required resources are made available by service providers via API integrations, and paid for per request, such as sending emails/SMS/phone calls, biometrics validation, etc.
### Spectral Rules
```yaml
# .spectral-api4.yaml
rules:
# Require rate limit documentation
rate-limit-headers-documented:
description: API should document rate limiting headers
severity: warn
given: $.paths[*][*].responses[*].headers
then:
function: schema
functionOptions:
schema:
type: object
properties:
X-RateLimit-Limit:
type: object
X-RateLimit-Remaining:
type: object
message: "Document rate limiting headers (X-RateLimit-*) to communicate consumption limits (OWASP API4:2023)"
# Detect pagination parameters
pagination-required:
description: List operations should support pagination
severity: warn
given: $.paths[*].get.parameters
then:
function: schema
functionOptions:
schema:
type: array
contains:
anyOf:
- properties:
name:
const: limit
- properties:
name:
const: offset
message: "List operations should support pagination (limit/offset or cursor) to prevent resource exhaustion (OWASP API4:2023)"
# Maximum response size documentation
response-size-limits:
description: Document maximum response sizes
severity: info
given: $.paths[*][*].responses[*]
then:
- field: description
function: pattern
functionOptions:
match: "(maximum|max|limit).*(size|length|count)"
message: "Consider documenting maximum response sizes (OWASP API4:2023)"
```
### Remediation
- Implement rate limiting and document limits in API specification
- Use pagination for all list operations (limit/offset or cursor-based)
- Document maximum request/response sizes
- Implement request timeout and maximum execution time limits
---
## API8:2023 - Security Misconfiguration
**Description**: APIs and the systems supporting them typically contain complex configurations, meant to make the APIs more customizable. Software and DevOps engineers can miss these configurations, or don't follow security best practices when it comes to configuration, opening the door for different types of attacks.
### Spectral Rules
```yaml
# .spectral-api8.yaml
rules:
# Require HTTPS for all servers
servers-use-https:
description: All API servers must use HTTPS
severity: error
given: $.servers[*].url
then:
function: pattern
functionOptions:
match: "^https://"
message: "Server URLs must use HTTPS protocol for secure communication (OWASP API8:2023)"
# Detect example.com in server URLs
no-example-servers:
description: Replace example server URLs with actual endpoints
severity: error
given: $.servers[*].url
then:
function: pattern
functionOptions:
notMatch: "example\\.com"
message: "Replace example.com with actual server URL (OWASP API8:2023)"
# Require security headers documentation
security-headers-documented:
description: Document security headers in responses
severity: warn
given: $.paths[*][*].responses[*].headers
then:
function: schema
functionOptions:
schema:
type: object
anyOf:
- required: [X-Content-Type-Options]
- required: [X-Frame-Options]
- required: [Strict-Transport-Security]
message: "Document security headers (X-Content-Type-Options, X-Frame-Options, HSTS) in responses (OWASP API8:2023)"
# CORS configuration review
cors-documented:
description: CORS should be properly configured and documented
severity: info
given: $.paths[*].options
then:
- field: responses
function: truthy
message: "Ensure CORS is properly configured - review Access-Control-* headers (OWASP API8:2023)"
```
### Remediation
- Use HTTPS for all API endpoints
- Configure and document security headers (HSTS, X-Content-Type-Options, X-Frame-Options)
- Properly configure CORS with specific origins (avoid wildcard in production)
- Disable unnecessary HTTP methods
- Remove verbose error messages in production
---
## API9:2023 - Improper Inventory Management
**Description**: APIs tend to expose more endpoints than traditional web applications, making proper and updated documentation highly important. A proper inventory of hosts and deployed API versions also are important to mitigate issues such as deprecated API versions and exposed debug endpoints.
### Spectral Rules
```yaml
# .spectral-api9.yaml
rules:
# Require API version
api-version-required:
description: API specification must include version
severity: error
given: $.info
then:
- field: version
function: truthy
message: "API version must be specified for proper inventory management (OWASP API9:2023)"
# Version format validation
semantic-versioning:
description: Use semantic versioning for API versions
severity: warn
given: $.info.version
then:
function: pattern
functionOptions:
match: "^\\d+\\.\\d+\\.\\d+"
message: "Use semantic versioning (MAJOR.MINOR.PATCH) for API versions (OWASP API9:2023)"
# Require contact information
contact-info-required:
description: API must include contact information
severity: warn
given: $.info
then:
- field: contact
function: truthy
message: "Include contact information for API support and security issues (OWASP API9:2023)"
# Require terms of service or license
legal-info-required:
description: API should include legal information
severity: info
given: $.info
then:
- field: license
function: truthy
message: "Include license or terms of service for API usage (OWASP API9:2023)"
# Deprecation documentation
deprecated-endpoints-documented:
description: Deprecated endpoints must be clearly marked
severity: warn
given: $.paths[*][*][?(@.deprecated == true)]
then:
- field: description
function: pattern
functionOptions:
match: "(deprecate|migrate|alternative|replacement)"
message: "Document deprecation details and migration path (OWASP API9:2023)"
```
### Remediation
- Maintain up-to-date API specification with version information
- Use semantic versioning for API versions
- Document all endpoints, including internal and deprecated ones
- Include contact information for security issues
- Implement API inventory management and discovery tools
- Remove or properly secure debug/admin endpoints in production
---
## Complete OWASP Ruleset Example
```yaml
# .spectral-owasp-complete.yaml
extends: ["spectral:oas"]
rules:
# API1: Broken Object Level Authorization
operation-security-defined:
severity: error
message: "All operations must have security defined (OWASP API1:2023)"
# API2: Broken Authentication
no-http-basic-auth:
description: Prohibit HTTP Basic authentication
severity: error
given: $.components.securitySchemes[*]
then:
field: scheme
function: pattern
functionOptions:
notMatch: "^basic$"
message: "HTTP Basic auth is insecure (OWASP API2:2023)"
# API3: Broken Object Property Level Authorization
no-additional-properties:
description: Prevent mass assignment
severity: warn
given: $.components.schemas[?(@.type == 'object')]
then:
field: additionalProperties
function: falsy
message: "Set additionalProperties to false (OWASP API3:2023)"
# API4: Unrestricted Resource Consumption
pagination-for-lists:
description: List operations should support pagination
severity: warn
given: $.paths[*].get
then:
function: truthy
message: "Implement pagination for list operations (OWASP API4:2023)"
# API8: Security Misconfiguration
servers-use-https:
description: All servers must use HTTPS
severity: error
given: $.servers[*].url
then:
function: pattern
functionOptions:
match: "^https://"
message: "Server URLs must use HTTPS (OWASP API8:2023)"
# API9: Improper Inventory Management
api-version-required:
description: API must specify version
severity: error
given: $.info
then:
field: version
function: truthy
message: "API version is required (OWASP API9:2023)"
```
## Additional Resources
- [OWASP API Security Top 10 2023](https://owasp.org/API-Security/editions/2023/en/0x11-t10/)
- [Spectral Rulesets Documentation](https://docs.stoplight.io/docs/spectral/docs/getting-started/rulesets.md)
- [OpenAPI Security Best Practices](https://swagger.io/docs/specification/authentication/)