Is an XSS attack possible under these constraints?



  • The output is:

    <img src="http://example.com/[input]" oncontextmenu="openUrl('http://example.com/[input]')">
    

    Where [input] is the user input, which is sanitised through this function:

    a => {
      a = String(a);
      a = this.replaceAll(a, "&", "&amp;");
      a = this.replaceAll(a, '"', "&quot;");
      a = this.replaceAll(a, "'", "&#39;");
      a = this.replaceAll(a, "<", "&lt;");
      return a = this.replaceAll(a, ">", "&gt;")
    }
    

    in other words, we seemingly can't break out or use quotes of any kind?

    Is an XSS attack possible at all under these constraints? Or is it possible to redirect the user to any domain besides example.com? Or indeed, load an image from (or make a request to) evil.com? Thanks!


  • QA Engineer

    Yes, XSS is possible.

    The first injection into src is secure, as " is HTML encoded, which is a proper defense against XSS in a HTML attribute value context.

    The second injection however is insecure, as it takes place in a JavaScript attribute context. Here, HTML encoding is not a proper defense and XSS can be achieved by injecting ');alert('1, which would give you (I replaced the undefined openUrl function for a self-contained POC):

    <img src="http://example.com/[input]" oncontextmenu="console.log('http://example.com/&#39;);alert(&#39;1')">
    

    While this may look secure at first sight, it is not. Right-clicking on the image will execute the payload. This is the case because the HTML parser first decodes the HTML-encoded ' before passing it to the JavaScript interpreter.

    The proper solution here is a bit tricky. You do need the HTML encoding for ", but you also need to backslash-escape ' (either in its HTML-encoded or basic form). \ will also need to be escaped.



Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2