I have been doing this challenge and I came across a super hard level that I think its all about DOM XSS.

I know it because I don't get any response from the server side and everything I insert won't reflect back because of brutal escaping.

Here is the source code of the page:

<script src="analytics.js"></script>

your cool xss


var queryDict = {};
location.href.substr(location.href.indexOf('?')+1).split("&").forEach( function(item) {
  queryDict[item.split("=")[0]] = item.split("=")[1]

a = '';

b = document.write('<b>' + decodeURIComponent(queryDict.p) + '</b>');

<!-- use your head and not automatic scanners like burp.. it will not help -->

Any help please?

  • 1
    Do you understand what DOM-based XSS is? What have you tried? – grc Aug 25 '16 at 9:16
  • @grc i understand Dom Xss i tried for example #<script>alert(1)</script> – Xozu Aug 25 '16 at 9:22
  • 2
    In the URL? Why #? – grc Aug 25 '16 at 9:32

I think you need to get better with your javascript first.

To answer your question, the below GET request is what you need to send



In the code


Here,you are taking the substring of the GET patameters in URL.

And then you are copying each of the GET parameter in to queryDict object as queryDict.key=value.

 forEach( function(item) {
  queryDict[item.split("=")[0]] = item.split("=")[1]

This assigns queryDict.p the value of %3Cscript%3Ealert(123)%3C%2Fscript%3E which is equalent to encodeURIComponent('<script>alert(123)</script>').

And finally

b = document.write('<b>' + decodeURIComponent(queryDict.p) + '</b>');

decodes the value of queryDict.p and injects it into DOM as a Javascript

  • 1
    Nice answer! One potential problem the OP might have had is that you have to explicitly URL encode all = (e.g. in onerror="...) as %3D. – Anders Aug 25 '16 at 9:37
  • @Anders You are Right, when he need to inject something like onerror="... in to DOM – Sravan Aug 25 '16 at 9:45
  • 1
    @Sravan thank you but its not the answer here is what i get from the challange:<body><center><h1>Hacking attempt!</h1><br> Your request is reported to administrator for further investigation!</center></body></html> – Xozu Aug 25 '16 at 11:02
  • 2
    @ShaiAlfasi If that is the case, there is some kind of filtering that is not done in the code you have shown us. It might be in analytics.js. Without that code, all we can do is guess, and that is sort of pointless. Try to find the code that does the filtering, analyze it, and see if you come up with someting. – Anders Aug 25 '16 at 11:09

For this case the main solution is to bypass the filter in the web page, encoding then pushing the payload into the URL will not work as I tried too many times and mainly the the script that will be decoded will be an printed in the web page and stored as a comment.

The filter as it filter any payload injected after the 'p=', even double encoded payload will not solve the issue.

The only way is to add the payload after the '#' so the filter will not scan it as I understand:


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.