Double URL Encoding: Causes, Examples, and Security Implications
- Double URL encoding happens when an already-encoded string is encoded a second time — %20 becomes %2520 because the % sign itself gets encoded as %25.
- It causes bugs when it happens accidentally, and is used in security attacks to bypass naive input filters.
- The fix is to always start from the unencoded value and encode exactly once.
Table of Contents
Double URL encoding is what happens when you run URL encoding on a string that's already been URL encoded. The percent sign from the first encoding gets encoded itself: %20 (encoded space) becomes %2520 (%25 is the encoding for %, followed by 20).
It causes two kinds of problems: accidental encoding bugs that break applications, and intentional double encoding used in security attacks to bypass input validation.
How Double URL Encoding Happens by Accident
The most common scenario: a value is encoded at one layer and then encoded again at another layer without the layers knowing about each other.
Example in a web app:
- A form submits a search value:
coffee & tea - The browser URL-encodes the form data:
coffee%20%26%20tea - A middleware layer encodes the query string again before passing it to the API:
coffee%2520%2526%2520tea - The API receives the double-encoded string and displays
coffee%20%26%20tea— the raw encoded text, not the original value
The fix: encode only at one layer. Identify which layer is responsible for encoding and make sure the other layers pass values through raw.
How to Detect if a String Is Double Encoded
A double-encoded string contains %25 sequences followed by two hex digits — this is the signature of an encoded percent sign.
Compare:
- Single encoding of "hello world":
hello%20world - Double encoding of "hello world":
hello%2520world - Single encoding of "50% off":
50%25%20off - Double encoding of "50% off":
50%2525%2520off
To check, paste the suspect string into the Mongoose URL Encoder decoder. Decode it once — if the result still looks percent-encoded (contains %XX sequences that represent readable characters), it was double encoded. Decode it a second time to get the original.
Double Encoding as a Security Attack Technique
Intentional double encoding is a technique attackers use to bypass naive input filters. If a web application blocks requests containing ../ (path traversal) or <script> (XSS), an attacker might try to slip past the filter using encoding.
Example path traversal bypass:
- Blocked:
../etc/passwd - Single encoded:
..%2Fetc%2Fpasswd— some filters catch this - Double encoded:
..%252Fetc%252Fpasswd— if the filter checks before decoding, it misses it; if the backend decodes twice, it reconstructs the original path
Proper defense: decode completely before validating, and validate after all decoding is complete. Never validate on the encoded form, then decode and use the result — the validation happened on a different string than what gets used.
How to Prevent Double Encoding Bugs
The core rule: encode exactly once, at the layer responsible for building the URL.
- Don't pre-encode values before passing them to a library that encodes automatically
- Don't encode a value stored in a database if it was encoded before storage
- When using URL-building helpers (
URLSearchParams,requests.get(params=...),http_build_query()), pass raw unencoded values — the library handles encoding - If you receive a URL from an external source and need to re-encode part of it, decode it first, modify, then encode once
For debugging: paste your encoded output into the Mongoose URL Encoder and decode it. If you see percent codes in the decoded output, you've got a double encoding problem.
Debug URL Encoding Issues — Free
Paste any suspect string into the Mongoose URL Encoder and decode it to see what's really inside. Runs entirely in your browser.
Open URL EncoderFrequently Asked Questions
Is double encoding always a bug?
In application code, almost always yes. The only legitimate use case is passing an encoded URL as a query parameter value inside another URL — in that case the outer URL needs to encode the percent signs of the inner URL. But this should be an intentional, documented design decision, not an accident.
My application receives %2520 — how do I fix it?
Find where in the encoding chain the value is being encoded twice. Common culprits: middleware that encodes query parameters when the client already encoded them, or a function that URL-encodes a value before passing it to an HTTP library that encodes again. Remove one layer of encoding.
Does a URL decoder automatically handle double encoding?
No. Standard decoders decode one layer at a time. To fully decode a double-encoded string, you need to decode twice. The Mongoose URL Encoder decodes one pass — if the output still shows %XX codes, paste it in and decode again.
Can double encoding be used to exploit my web application?
Yes, if your input validation happens before decoding, or if your application decodes multiple times. Audit your request processing pipeline to ensure decoding is complete before any validation or sanitization runs.

