<!-- AUTO-GENERATED by export-skills.py — DO NOT EDIT -->
---
name: owasp-top10
description: OWASP Top 10 (2021) web application security risks with prevention controls, detection techniques, and remediation guidance
---

# OWASP Top 10 Web Application Security Risks

## Overview

The OWASP Top 10 (2021 edition) is the most widely referenced standard for web application security awareness. It represents a broad consensus on the most critical security risks facing web applications, ranked by prevalence, exploitability, and impact. Security agents use this skill to identify, classify, and remediate web application vulnerabilities across the full development lifecycle.

Each category aggregates related CWEs (Common Weakness Enumerations) and provides actionable prevention guidance. The 2021 edition introduced three new categories (Insecure Design, Software and Data Integrity Failures, SSRF) and restructured several existing ones from the 2017 edition.

## When to Use This Skill

- Performing security code reviews on web applications
- Triaging vulnerability scan results from DAST/SAST tools
- Designing security controls for new application features
- Writing security requirements or acceptance criteria for stories
- Assessing third-party applications or APIs for security posture
- Training developers on secure coding practices
- Building security test cases for CI/CD pipelines

## How It Works

### Step 1: Identify the Risk Category

Map the observed vulnerability or concern to one of the 10 categories:

| Rank | Category                                    | Key CWEs                          |
|------|---------------------------------------------|-----------------------------------|
| A01  | Broken Access Control                       | CWE-200, CWE-284, CWE-285, CWE-352 |
| A02  | Cryptographic Failures                      | CWE-259, CWE-327, CWE-328, CWE-331 |
| A03  | Injection                                   | CWE-79, CWE-89, CWE-78, CWE-94     |
| A04  | Insecure Design                             | CWE-209, CWE-256, CWE-501, CWE-522 |
| A05  | Security Misconfiguration                   | CWE-16, CWE-611, CWE-1004           |
| A06  | Vulnerable and Outdated Components          | CWE-1104                             |
| A07  | Identification and Authentication Failures  | CWE-287, CWE-297, CWE-384          |
| A08  | Software and Data Integrity Failures        | CWE-502, CWE-829                     |
| A09  | Security Logging and Monitoring Failures    | CWE-117, CWE-223, CWE-778          |
| A10  | Server-Side Request Forgery (SSRF)          | CWE-918                              |

### Step 2: Assess the Vulnerability

For the identified category, determine:
- **Severity:** What is the potential business impact (data breach, service disruption, compliance violation)?
- **Exploitability:** How easy is it to exploit (unauthenticated, requires valid session, requires admin)?
- **Scope:** How many endpoints, components, or users are affected?
- **Evidence:** What specific code patterns, configurations, or behaviors indicate the vulnerability?

### Step 3: Apply Prevention Controls

Each category has specific prevention strategies. Apply the controls relevant to your technology stack:

**A01 - Broken Access Control:**
- Deny by default; explicitly grant permissions
- Implement server-side access control checks on every request
- Disable directory listing and remove metadata files from web roots
- Rate-limit API and controller access to minimize automated attacks
- Invalidate JWT tokens on the server after logout
- Enforce record-level ownership checks (users can only access their own data)

**A02 - Cryptographic Failures:**
- Classify data by sensitivity and apply controls per classification
- Encrypt all data in transit (TLS 1.2+) and at rest (AES-256)
- Do not use deprecated algorithms (MD5, SHA1, DES, RC4)
- Use authenticated encryption (AES-GCM) instead of unauthenticated modes
- Generate keys using cryptographically secure PRNGs
- Store passwords with adaptive hashing (bcrypt, scrypt, Argon2id)

**A03 - Injection:**
- Use parameterized queries or prepared statements for all database access
- Use ORM frameworks with safe query-building methods
- Validate and sanitize all user input on the server side
- Escape output based on context (HTML, JS, URL, CSS, LDAP)
- Deploy WAF rules as a defense-in-depth measure
- Use LIMIT clauses in queries to prevent mass data disclosure

**A04 - Insecure Design:**
- Use threat modeling during the design phase (STRIDE, PASTA)
- Establish secure design patterns in a reference architecture
- Write security-focused user stories and abuse cases
- Implement rate limiting and resource quotas at the design level
- Segregate tenant data architecturally, not just logically
- Use plausibility checks and business logic validation

**A05 - Security Misconfiguration:**
- Automate hardening with configuration management (Ansible, Terraform)
- Remove unused features, components, frameworks, and documentation
- Review and update configurations as part of the patch management process
- Implement segmented application architecture with proper ACLs
- Send security directives to clients (CSP, X-Content-Type-Options, HSTS)
- Disable XML external entity processing in all XML parsers

**A06 - Vulnerable and Outdated Components:**
- Maintain an inventory of all client-side and server-side components
- Monitor CVE databases and security advisories continuously
- Use Software Composition Analysis (SCA) in CI/CD pipelines
- Pin dependency versions and audit lock files for unexpected changes
- Obtain components only from official sources over secure links
- Remove unused dependencies and orphaned components

**A07 - Identification and Authentication Failures:**
- Implement multi-factor authentication (MFA) for all accounts
- Enforce strong password policies (minimum 12 characters, no known breached passwords)
- Use proven session management (server-generated, high-entropy session IDs)
- Rate-limit and monitor login attempts; implement account lockout or CAPTCHA
- Harden credential recovery flows against enumeration attacks
- Use the same generic message for all authentication failure outcomes

**A08 - Software and Data Integrity Failures:**
- Verify digital signatures on software updates and dependencies
- Use tools like npm audit, pip-audit, or OWASP Dependency-Check in CI/CD
- Do not deserialize untrusted data; if unavoidable, enforce strict type constraints
- Implement code review processes for all changes to CI/CD pipelines
- Ensure CI/CD pipelines have proper segregation, configuration, and access control
- Use Subresource Integrity (SRI) for externally hosted scripts

**A09 - Security Logging and Monitoring Failures:**
- Log all authentication events, access control failures, and input validation failures
- Ensure logs include sufficient context (who, what, when, where, outcome)
- Use structured logging (JSON) for machine-parseable log ingestion
- Centralize logs in a SIEM with tamper-evident storage
- Establish alerting thresholds and escalation procedures
- Test incident detection with regular tabletop exercises

**A10 - Server-Side Request Forgery (SSRF):**
- Validate and sanitize all client-supplied URLs
- Enforce allowlists for permitted destination hosts, ports, and protocols
- Do not send raw responses from backend requests to clients
- Disable HTTP redirects in server-side HTTP clients
- Deploy network-level segmentation (deny outbound to internal ranges by default)
- Use metadata endpoint protection (e.g., IMDSv2 on AWS)

### Step 4: Test with Tools

Use appropriate security testing tools to validate:
- **SAST:** Semgrep, SonarQube, Bandit (Python), ESLint security plugins
- **DAST:** OWASP ZAP, Burp Suite, Nuclei
- **SCA:** Snyk, Dependabot, Trivy, OWASP Dependency-Check
- **IAM Testing:** AuthMatrix (Burp extension), manual role-based testing
- **SSRF Testing:** SSRFmap, manual curl-based probes against metadata endpoints

### Step 5: Verify Remediation

After applying fixes, confirm the vulnerability is resolved:
- Re-run the original test or scan that identified the issue
- Verify the fix does not introduce regressions in other areas
- Update the security test suite with a regression test for the vulnerability
- Document the remediation in the security issue tracker

## Examples

### Example 1: Detecting and Fixing SQL Injection (A03)

Vulnerable code (Python/FastAPI):

```python
# VULNERABLE - string concatenation in SQL query
@router.get("/users")
async def get_users(search: str, db: AsyncSession = Depends(get_db)):
    query = f"SELECT * FROM users WHERE name LIKE '%{search}%'"
    result = await db.execute(text(query))
    return result.fetchall()
```

Fixed code using parameterized queries:

```python
# SECURE - parameterized query prevents SQL injection
@router.get("/users")
async def get_users(search: str, db: AsyncSession = Depends(get_db)):
    query = text("SELECT * FROM users WHERE name LIKE :search")
    result = await db.execute(query, {"search": f"%{search}%"})
    return result.fetchall()
```

Even better, use SQLAlchemy ORM:

```python
# SECURE - ORM with safe query building
@router.get("/users")
async def get_users(search: str, db: AsyncSession = Depends(get_db)):
    stmt = select(User).where(User.name.ilike(f"%{search}%")).limit(100)
    result = await db.execute(stmt)
    return result.scalars().all()
```

### Example 2: Implementing Proper Access Control (A01)

Vulnerable code (no ownership check):

```python
# VULNERABLE - any authenticated user can access any tenant's data
@router.get("/tenants/{tenant_id}/reports/{report_id}")
async def get_report(tenant_id: str, report_id: str, db: AsyncSession = Depends(get_db)):
    report = await db.get(Report, report_id)
    if not report:
        raise HTTPException(status_code=404)
    return report
```

Fixed code with RBAC and tenant isolation:

```python
# SECURE - enforces tenant isolation and role-based access
@router.get("/tenants/{tenant_id}/reports/{report_id}")
async def get_report(
    tenant_id: str,
    report_id: str,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    # Verify user belongs to the requested tenant
    if current_user.tenant_id != tenant_id:
        raise HTTPException(status_code=403, detail="Access denied")

    # Verify user has the required role
    if "reports:read" not in current_user.permissions:
        raise HTTPException(status_code=403, detail="Insufficient permissions")

    # Fetch with tenant scoping to prevent IDOR
    stmt = (
        select(Report)
        .where(Report.id == report_id, Report.tenant_id == tenant_id)
    )
    report = (await db.execute(stmt)).scalar_one_or_none()
    if not report:
        raise HTTPException(status_code=404)
    return report
```

### Example 3: Secure Logging Configuration (A09)

```python
import logging
import json
from datetime import datetime, timezone


class SecurityAuditFormatter(logging.Formatter):
    """Structured JSON formatter for security-relevant events."""

    def format(self, record: logging.LogRecord) -> str:
        log_entry = {
            "timestamp": datetime.now(timezone.utc).isoformat(),
            "level": record.levelname,
            "logger": record.name,
            "message": record.getMessage(),
            "module": record.module,
            "function": record.funcName,
        }
        # Add security context if present
        for field in ("user_id", "tenant_id", "action", "resource", "outcome", "ip_address"):
            if hasattr(record, field):
                log_entry[field] = getattr(record, field)
        return json.dumps(log_entry)


# Configure security audit logger
security_logger = logging.getLogger("security.audit")
security_logger.setLevel(logging.INFO)

handler = logging.StreamHandler()
handler.setFormatter(SecurityAuditFormatter())
security_logger.addHandler(handler)


# Usage in authentication flow
def log_auth_event(user_id: str, tenant_id: str, action: str, outcome: str, ip: str):
    security_logger.info(
        "Authentication event",
        extra={
            "user_id": user_id,
            "tenant_id": tenant_id,
            "action": action,
            "outcome": outcome,
            "ip_address": ip,
        },
    )


# Example calls
log_auth_event("usr_123", "tnt_456", "login", "success", "203.0.113.42")
log_auth_event("usr_789", "tnt_456", "login", "failure_invalid_password", "198.51.100.7")
```

## Best Practices

### Do This

- Apply defense in depth: combine input validation, parameterized queries, and WAF rules
- Treat all client input as untrusted, including headers, cookies, and URL parameters
- Use security linters and SAST tools in pre-commit hooks and CI pipelines
- Conduct threat modeling for every new feature during the design phase
- Keep dependencies updated and monitor for new CVEs continuously
- Log security events with structured context and centralize in a SIEM
- Test access control for every role and permission combination
- Use allowlists over denylists for input validation and URL filtering

### Don't Do This

- Do not rely solely on client-side validation for security controls
- Do not store secrets, API keys, or credentials in source code or client-side storage
- Do not use custom cryptographic implementations; use vetted libraries
- Do not disable security headers (CSP, HSTS, X-Frame-Options) for convenience
- Do not log sensitive data (passwords, tokens, PII) in application logs
- Do not trust deserialized data from untrusted sources without strict validation
- Do not expose detailed error messages or stack traces to end users
- Do not assume internal APIs are safe from SSRF; enforce network segmentation

## Security Checklist

**A01 - Broken Access Control:**
- [ ] Server-side access control enforced on every endpoint
- [ ] Record-level ownership checks prevent IDOR vulnerabilities
- [ ] CORS policy restricts allowed origins to trusted domains
- [ ] Directory listing disabled; sensitive files excluded from web root

**A02 - Cryptographic Failures:**
- [ ] All data in transit protected with TLS 1.2+
- [ ] Sensitive data at rest encrypted with AES-256 or equivalent
- [ ] Passwords hashed with Argon2id, bcrypt, or scrypt
- [ ] No deprecated algorithms (MD5, SHA1, DES) in use

**A03 - Injection:**
- [ ] All database queries use parameterized statements or ORM
- [ ] Output encoding applied per context (HTML, JS, URL)
- [ ] Input validation enforced on all server-side entry points

**A04 - Insecure Design:**
- [ ] Threat model documented for critical application flows
- [ ] Rate limiting applied to authentication and sensitive endpoints
- [ ] Abuse cases and negative test scenarios included in test plans

**A05 - Security Misconfiguration:**
- [ ] Default credentials removed or changed on all components
- [ ] Unnecessary features and debug endpoints disabled in production
- [ ] Security headers configured (CSP, HSTS, X-Content-Type-Options)

**A06 - Vulnerable Components:**
- [ ] Software Composition Analysis (SCA) runs in CI/CD pipeline
- [ ] Dependency update policy enforced (critical CVEs patched within 48 hours)
- [ ] Component inventory maintained and reviewed quarterly

**A07 - Authentication Failures:**
- [ ] Multi-factor authentication available and enforced for privileged accounts
- [ ] Session tokens are high-entropy, server-generated, and expire appropriately
- [ ] Account lockout or progressive delays mitigate brute-force attacks

**A08 - Integrity Failures:**
- [ ] CI/CD pipeline changes require code review and approval
- [ ] Dependencies verified with checksums or digital signatures
- [ ] Deserialization of untrusted data is avoided or strictly constrained

**A09 - Logging Failures:**
- [ ] All authentication, access control, and input validation failures are logged
- [ ] Logs are structured (JSON), centralized, and tamper-evident
- [ ] Alerting configured for high-severity security events

**A10 - SSRF:**
- [ ] Server-side URL requests validate against an allowlist of permitted destinations
- [ ] Cloud metadata endpoints protected (IMDSv2 or equivalent)
- [ ] HTTP redirect following disabled in server-side HTTP clients

## Related Skills

- @api-security-patterns - API-specific security patterns including authentication, rate limiting, and input validation
- @cwe-sans-top25 - CWE/SANS Top 25 most dangerous software weaknesses with deeper CWE mapping
- @owasp-api-top10 - OWASP API Security Top 10 for API-specific vulnerabilities

## Additional Resources

- [OWASP Top 10 (2021)](https://owasp.org/Top10/) - Official OWASP Top 10 project page
- [OWASP Cheat Sheet Series](https://cheatsheetseries.owasp.org/) - Practical secure coding guidance
- [OWASP Testing Guide](https://owasp.org/www-project-web-security-testing-guide/) - Comprehensive security testing methodology
- [OWASP ASVS](https://owasp.org/www-project-application-security-verification-standard/) - Application Security Verification Standard
- [CWE/MITRE](https://cwe.mitre.org/) - Common Weakness Enumeration database
- [OWASP ZAP](https://www.zaproxy.org/) - Free DAST tool for finding web application vulnerabilities

<!-- Source: .faos/custom/skills/security/owasp-top10/SKILL.md -->
