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, '&')
.replace(/"/g, '"')
.replace(/'/g, ''')
.replace(/</g, '<')
.replace(/>/g, '>');
}