Skip to content

Instantly share code, notes, and snippets.

@harisec
Created July 13, 2024 16:06
Show Gist options
  • Save harisec/1892602380edd5aee5c44316e8ac45fd to your computer and use it in GitHub Desktop.
Save harisec/1892602380edd5aee5c44316e8ac45fd to your computer and use it in GitHub Desktop.
----------------------------------------------------------------------------------------------------
Question:
The following code is exploitable in modern browsers? Take into consideration that html separator characters like < and > from document.URL are automatically URL encoded in modern browsers.
example URL:
http://localhost:3000/#context=before<script>after
document.URL
'http://localhost:3000/#context=before%3Cscript%3Eafter'
code:
<script>
var pos=document.URL.indexOf("context=")+8;
document.write(document.URL.substring(pos));
</script>
----------------------------------------------------------------------------------------------------
Individual Responses:
----------------------------------------------------------------------------------------------------
[gpt-4]
The code you've posted can be exploitable in modern browsers, though modern browsers do have some defenses against certain types of attacks such as Cross-Site Scripting (XSS). Let me explain how the exploit would work and why the code can be considered vulnerable.
### How the Code Can Be Exploited
1. **Payload Insertion:**
- The attacker can craft a URL that includes a script tag or other malicious content after the `context=` parameter.
- Example malicious URL: `http://localhost:3000/#context=<script>alert('XSS')</script>`
2. **URL-Encoding:**
- When the browser encodes the URL characters `<` and `>`, the above URL becomes:
```
http://localhost:3000/#context=%3Cscript%3Ealert('XSS')%3C/script%3E
```
3. **JavaScript Execution:**
- Your code snippet extracts the value after `context=`, decodes it, and writes it directly to the document:
```javascript
<script>
var pos=document.URL.indexOf("context=")+8;
document.write(decodeURIComponent(document.URL.substring(pos)));
</script>
```
- `document.URL.substring(pos)` retrieves the encoded part: `%3Cscript%3Ealert('XSS')%3C/script%3E`
- `decodeURIComponent('%3Cscript%3Ealert('XSS')%3C/script%3E')` decodes it to `<script>alert('XSS')</script>`
- `document.write('<script>alert('XSS')</script>')` writes this decoded, potentially malicious script into the HTML, and the script will execute.
### Why This Is a Problem
- **Document Write:** Using `document.write()` to insert untrusted content into the DOM can result in the execution of malicious JavaScript code.
- **Direct Injection from URL:** The content from the URL can be controlled by an attacker. If this content is directly written into the document without proper sanitization or encoding, it can lead to XSS attacks.
### Recommendations to Fix the Vulnerability
1. **Avoid Using `document.write()`**: Especially avoid it with untrusted data.
2. **Sanitize Input**: Make sure to sanitize any user input or URL parameters before using them in your HTML.
3. **Use Text Node or InnerText**:
- Consider inserting potentially unsafe data as text, not as HTML. For example:
```javascript
<script>
var pos = document.URL.indexOf("context=") + 8;
var content = decodeURIComponent(document.URL.substring(pos));
var textNode = document.createTextNode(content);
document.body.appendChild(textNode);
</script>
```
In summary, the code you provided is indeed exploitable in modern browsers, primarily due to the use of `document.write()` without sanitization. An attacker could craft a URL that includes malicious scripts, which when decoded and written to the document, will execute in the user's browser. Avoiding `document.write()` and properly sanitizing input are important steps to mitigate such vulnerabilities.
----------------------------------------------------------------------------------------------------
[claude]
You're correct that modern browsers automatically URL encode special characters like < and > in the URL. However, the code you've provided is still potentially exploitable, despite this encoding. Here's why:
1. URL Fragment Handling: The code is using document.URL, which includes the entire URL, including the fragment (part after #). Browsers do not typically encode the fragment part of the URL.
2. document.write(): The use of document.write() is a significant security risk. It directly writes content to the document, and if that content includes any HTML or JavaScript, it will be executed.
3. No Sanitization: The code doesn't perform any sanitization or encoding on the output. It directly writes whatever is after "context=" to the document.
4. Decoded Output: Even though < and > are encoded in document.URL, when you use substring() and then document.write(), the content is effectively decoded before being written to the document.
Here's how an attacker could potentially exploit this:
1. Create a malicious URL:
http://localhost:3000/#context=<script>alert('XSS')</script>
2. When this URL is loaded, document.URL will contain:
http://localhost:3000/#context=<script>alert('XSS')</script>
3. The script will extract everything after "context=" and write it to the document.
4. The browser will then interpret <script>alert('XSS')</script> as actual code and execute it.
To make this code safer:
1. Avoid using document.write(). Instead, use safer DOM manipulation methods.
2. Always sanitize and encode user input before using it in your application.
3. Consider using Content Security Policy (CSP) headers to restrict what can be executed on your page.
4. Use template literals or DOM methods to insert content rather than concatenating strings.
Here's a safer version:
```javascript
<script>
var pos = new URL(document.URL).hash.indexOf("context=") + 8;
var content = new URL(document.URL).hash.substring(pos);
var safeContent = document.createTextNode(content);
document.body.appendChild(safeContent);
</script>
```
This version uses createTextNode() to ensure the content is treated as text, not HTML or JavaScript, preventing XSS attacks.
----------------------------------------------------------------------------------------------------
[deepseek]
Yes, the provided code is exploitable in modern browsers, despite the fact that HTML separator characters like `<` and `>` are automatically URL-encoded in modern browsers. The exploit arises from the use of `document.write` to dynamically generate content based on the URL.
Here's a breakdown of why this code is vulnerable:
1. **URL Encoding**: While modern browsers do URL-encode characters like `<` and `>` in the URL, they are not encoded in the fragment part of the URL (the part after the `#`). This means that `%3C` (which is `<`) and `%3E` (which is `>`) are still present in the URL.
2. **document.write**: The `document.write` method is used to output content directly into the document. If this content includes HTML tags (like `<script>`), they will be interpreted as part of the HTML document.
3. **Exploit**: By crafting a URL with a specially encoded payload in the fragment part, an attacker can inject malicious scripts into the page. For example, a URL like `http://localhost:3000/#context=before%3Cscript%3Ealert('XSS')%3C/script%3Eafter` will result in the following code being written to the document:
```html
before<script>alert('XSS')</script>after
```
This will execute the `alert('XSS')` script in the context of the page.
To mitigate this vulnerability, avoid using `document.write` for dynamic content, especially when that content is derived from user input or URLs. Instead, use safer methods like DOM manipulation with `createElement`, `appendChild`, and other DOM methods.
Here's an example of how you might rewrite the code to avoid the vulnerability:
```javascript
<script>
var pos = document.URL.indexOf("context=") + 8;
var content = document.URL.substring(pos);
var decodedContent = decodeURIComponent(content);
var textNode = document.createTextNode(decodedContent);
document.body.appendChild(textNode);
</script>
```
In this revised version, the content is decoded and then added as a text node to the document body, which prevents it from being interpreted as HTML.
----------------------------------------------------------------------------------------------------
Aggregated Response:
----------------------------------------------------------------------------------------------------
Thank you for providing those model responses. I'll synthesize them into a comprehensive, accurate answer to the user's question about the exploitability of the provided code in modern browsers.
The code provided is indeed exploitable in modern browsers, despite the automatic URL encoding of special characters like < and > in the URL. This vulnerability exists due to several factors:
1. URL Fragment Handling:
The code uses document.URL, which includes the entire URL, including the fragment (part after #). Browsers typically do not encode the fragment part of the URL, leaving it vulnerable to manipulation.
2. Use of document.write():
This method is a significant security risk as it directly writes content to the document. Any HTML or JavaScript included in this content will be executed by the browser.
3. Lack of Input Sanitization:
The code doesn't perform any sanitization or encoding on the output. It directly writes whatever comes after "context=" to the document.
4. Automatic Decoding:
Even though < and > are encoded in document.URL, using substring() and then document.write() effectively decodes the content before writing it to the document.
Exploit Example:
An attacker could craft a malicious URL like:
http://localhost:3000/#context=<script>alert('XSS')</script>
When this URL is loaded:
1. document.URL will contain the full URL, including the unencoded fragment.
2. The script extracts everything after "context=" and writes it to the document.
3. The browser interprets <script>alert('XSS')</script> as actual code and executes it.
To mitigate this vulnerability:
1. Avoid using document.write(). Instead, use safer DOM manipulation methods.
2. Always sanitize and encode user input before using it in your application.
3. Use Content Security Policy (CSP) headers to restrict what can be executed on your page.
4. Employ safer methods for inserting content, such as template literals or appropriate DOM methods.
Here's a safer version of the code:
```javascript
<script>
var pos = new URL(document.URL).hash.indexOf("context=") + 8;
var content = new URL(document.URL).hash.substring(pos);
var safeContent = document.createTextNode(decodeURIComponent(content));
document.body.appendChild(safeContent);
</script>
```
This version uses createTextNode() to ensure the content is treated as text, not HTML or JavaScript, preventing XSS attacks. It also properly decodes the URL-encoded content while maintaining security.
In conclusion, while modern browsers do provide some built-in protections against certain types of attacks, the original code remains vulnerable due to its use of unsafe methods and lack of proper input handling. By implementing the suggested mitigations and using safer coding practices, you can significantly reduce the risk of XSS and similar attacks.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment