Double URL Encoding Bypass
TL;DR
Filters operating on URL-decoded input miss double-encoded payloads — %2527 decodes to %27 which decodes to ' — always decode completely before filtering.
Explanation
URL encoding: %27 = '. Double encoding: %2527 = %27 = '. If a WAF or filter decodes once and checks, then the application decodes again, the second decode reveals the payload. Common in path traversal (%2e%2e%2f = ../), XSS (%253Cscript%253E), and SQL injection. PHP's urldecode() and $_GET automatic decoding create opportunities. Defences: filter after all decoding is complete, use parameterised queries (immune to encoding tricks), validate against a whitelist of allowed characters after normalisation, use realpath() to resolve paths before checking.
Common Misconception
✗ URL-decoding input once before filtering is sufficient — attackers double-encode specifically to survive single-decode filters.
Why It Matters
Double encoding is a common WAF bypass technique — applications that rely on perimeter filtering without proper input normalisation remain vulnerable.
Common Mistakes
- Filtering raw $_GET without checking if values are further encoded.
- Path traversal checks that operate before realpath() normalisation.
- Trusting WAF filtering without validating at the application layer.
Code Examples
✗ Vulnerable
// Checks for ../ but misses %2e%2e%2f or %252e%252e%252f:
if (strpos($_GET['file'], '../') !== false) {
die('Invalid path');
}
readfile('/uploads/' . $_GET['file']);
✓ Fixed
$file = $_GET['file'] ?? '';
// Fully normalise before validating
$path = realpath('/uploads/' . $file);
if ($path === false || !str_starts_with($path, '/uploads/')) {
http_response_code(400); die('Invalid path');
}
readfile($path);
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
22 Mar 2026
Views
36
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 0
No pings yet today
No pings yesterday
Google 12
Perplexity 7
Amazonbot 6
Unknown AI 3
ChatGPT 2
Ahrefs 1
Also referenced
How they use it
crawler 28
crawler_json 1
pre-tracking 2
Related categories
⚡
DEV INTEL
Tools & Severity
🟠 High
⚙ Fix effort: Medium
⚡ Quick Fix
Use realpath() to normalise all paths before validation. Filter after complete decoding. Use parameterised queries. Never rely on encoding-based filtering alone.
📦 Applies To
PHP 4.0+
web
🔗 Prerequisites
🔍 Detection Hints
\$_GET|\$_POST|urldecode
Auto-detectable:
✗ No
semgrep
⚠ Related Problems
🤖 AI Agent
Confidence: Medium
False Positives: Medium
✗ Manual fix
Fix: Medium
Context: Function
Tests: Update
CWE-22
CWE-79
CWE-116