My gut feeling is that the following should be attackable:

$("<td><a href=somefile.php?url="+encodeURIComponent(somevar)+">Download Here</a></td>");

In contrast to

$("<td><a href=\"somefile.php?url="+encodeURIComponent(somevar)+"\">Download Here</a></td>");

For a cross site scripting attack if the user has control over somevar, yet I can't seem to find the specific attack. Am I mistaken?


From MDN:

encodeURIComponent escapes all characters except the following: alphabetic, decimal digits,

- _ . ! ~ * ' ( )

You would normally require a space character to add another attribute (such as onclick), unfortunately this will be encoded as part of the URI.

However, from OWASP XSS (Cross Site Scripting) Prevention Cheat Sheet:

Unquoted attributes can be broken out of with many characters, including [space] % * + , - / ; < = > ^ and |

So you might want to try the - or * characters to attempt to create a new attribute.

e.g. set somevar to http://www.example.com-onclick=alert('xss') or http://www.example.com*onclick=alert('xss')

Your mileage may vary between browsers and unfortunately the = will still be URL encoded so you will also have that hurdle to overcome. So even though the value is not quoted nor encoded properly, it may not be possible to turn this encoding flaw into an XSS exploit.

Your second example is more secure, although the value should really be HTML encoded:

$("<td><a href=somefile.php?url=\""+htmlEscape(encodeURIComponent(somevar))+"\">Download Here</a></td>");

where htmlEscape is:-

function htmlEscape(str) {
    return String(str)
            .replace(/&/g, '&amp;')
            .replace(/"/g, '&quot;')
            .replace(/'/g, '&#39;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;');

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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