0

I was doing the following PortSwigger Lab on cross site scripting (XSS).

The following payload works perfectly.

http://foo?'-alert(1)-'

Which is input into the following section of the webpage.

<img src="/resources/images/avatarDefault.svg" class="avatar">
<a id="author" href="http://foo.com&apos;-alert(1)-&apos;" onclick="var tracker={track(){}};tracker.track('http://foo.com&apos;-alert(1)-&apos;');">last</a> | 16 June 2022

Could someone please explain how the payload works, for example whether the &apos escapes the HTML or the JavaScript code, and why that results in alert() being executed?

1 Answer 1

1

When you place this payload in the website parameter value, sending a request like this:

POST /post/comment HTTP/1.1
csrf=rJXP2IH8tuMQffr4Ao1XAW5pjCeVm3T8&postId=1&comment=test&name=test&email=test%40test.pl&website=http%3a%2f%2ffoo%3f%26apos%3b-alert(1)-%26apos%3b

this value is inserted into the HTML response inside onclick attribute:

enter image description here

&apos; is a valid HTML5 predefined character entity that represents an apostrophe or a single quote. The script is being executed because before the JavaScript is interpreted, the browser first decodes the value of the onclick attribute. Generally when the browser parses tag attributes, it automatically HTML decodes their values.

So this:

<a id="author" href="http://foo?&apos;-alert(1)-&apos;" onclick="var tracker={track(){}};tracker.track('http://foo?&apos;-alert(1)-&apos;');">test</a>

is interpreted by the browser as this:

<a id="author" href="http://foo?&apos;-alert(1)-&apos;" onclick="var tracker={track(){}};tracker.track('http://foo?'-alert(1)-'');">test</a>

The entities are decoded as quotes, which are string delimited, resulting in a successful alert execution.

1
  • I like your reply, especially the fact that the HTML's values are decoded before the JavaScript is executed. What I found out myself, was this part ('foo?'-alert(1)-'') first executes the alert(1) then whatever is returned gets subtracted by the 'foo' and empty '' string, resulting in a NaN value. I was unfamiliar with JavaScript being this quirky, I doubt it would be allowed in other languages.
    – questioner
    Jun 20, 2022 at 12:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .