Reflected XSS with SVG Markup

Level: Practitioner

Today we will solve Portswigger’s “Reflected XSS with some SVG markup allowed” lab from their XSS (Cross-site scripting) series.

This is the information that we are starting with:

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.

When we open the lab, we see a search bar. Let’s try entering a random XSS payload there. For example I tried <script>alert(1)</script> and <img src=1 onerror=alert(1)>, both of which returned a “Tag is not allowed error”.

Okay, so it looks like (at least some, probably most) tags are blocked. The next thing that we might want to do is to see whether we can find any tags that are not blocked. For this we can use Burp Intruder. Let’s find the GET /?search=payload request in HTTP History and send it to the Intruder. Then let’s click “Clear §”, insert angle brackets instead of our previous payload and then let’s click “Add §” twice between the angle brackets so the value of the search term is now <§§> :

Now we need to add some payloads. For this we can use Portswigger’s handy XSS cheat sheet . Let’s click “Copy tags to clipboard”, then let’s open the “Payloads” tab in the Intruder and paste the tags under the “Payload settings” option:

Then let’s start the attack. Once we have the results, we can sort them by status. We see that the majority of payloads result in a 400 status code, but there are a few that give us a much happier 200 response!:

When we take a look at the cheat sheet again, we can see that <animatetransform> is a tag that is used within the <svg> tag. Luckily for us, neither of the tags is blocked, so let’s try finding a working payload containing these two tags. For that we need to choose “svg->animatetransform”, “all events” and “all browsers” in the cheat sheet:

As a result, we see three event handlers that don’t require user interaction, so let’s try these out:

After trying these three, it turns out that only the first one gives us a popup, the other two result in an “Event is not allowed” error. Since there were only three options to try out, I did it manually, but in case of more options it wouldn’t be so convenient to try them out one by one. In that case Burp Intruder would help us out again, so let’s see how to use that instead of this manual approach.

Let’s go back to the Intruder and replace our current payload with <svg><animatetransform%20=1>, then let’s add two § signs before the = sign, so now the value of the search term is <svg><animatetransform%20§§=1> :

Now we need to add a payload list. Let’s click “Copy events to clipboard” in the XSS cheat sheet, open the “Payloads” tab in the Intruder and paste the tags under the “Payload settings” option, just like before. Then let’s start the attack. As expected, we only get one result with the 200 status code and that is “onbegin”:

Then we find the correct payload in the cheat sheet, enter that into the search bar, et voilà, the lab is solved!