Reputation: 4273
I get a string, from an external clientside script, which must later be attached as part of an url. Now I am wondering what is the best way to santitize such data?
The string I get will have a structure like this:
dynamicVal#staticVal:dynamicVal
This value will then be added to an url:
http://the-page.com/dynamicVal#staticVal:dynamicVal
The url is then used as followed:
$link = htmlspecialchars("http://external-page.com/dynamicVal#staticVal:dynamicVal", ENT_QUOTES);
$var = "<a href=\"javascript: window.open('$link')\">'Open URL'</a>";
Problem is, htmlspecialchars
wont help to prevent execution of random javascript code, e.g. by adding this alert to the value:
dynamicVal#staticVal:dynamicVal'+alert(\"breakout\")+'
Using rawurlencode
wont help either, because it is not a value of a parameter but a real part of the url.
So what is the best way to sanitize the passed string when concatenating to the url?
Thanks in advance.
Edit:
Using rawurlencode
only on the dynamic parts actually also didn't solve the issue, the javascript still got executed.
Test snippet:
$splitVal = "#staticVal:";
$tmpArr = explode($splitVal, "dynamicVal#staticVal:dynamicVal'+alert(\"breakout\")+'");
$link = htmlspecialchars(sprintf("http://external-page.com/"."%s$splitVal%s", rawurlencode($tmpArr[0]), rawurlencode($tmpArr[1])), ENT_QUOTES);
echo "<a href=\"javascript: window.open('$link')\">'Open URL'</a>";
Edit2:
Using json_encode
when passing the string as javascript argument didn't help either.
Adapted test snippet:
$splitVal = "#staticVal:";
$tmpArr = explode($splitVal, "dynamicVal#staticVal:dynamicVal\"+alert('breakout')+\"");
$link = htmlspecialchars(sprintf("http://external-page.com/"."%s$splitVal%s", rawurlencode($tmpArr[0]), rawurlencode($tmpArr[1])), ENT_QUOTES);
echo "<a href=\"javascript: window.open(".htmlspecialchars(json_encode($link), ENT_QUOTES).")\">'Open URL'</a>";
Adaptions done:
Switched the quotes in the malicous JS.
Moved htmlspecialchars
around json_encode
, because a double quoted string gets returned which would break the html otherwise.
Upvotes: 0
Views: 1509
Reputation: 4273
For completenes, I was able to solve that issue by simply putting addslashes
on the dynamic part before using rawurlencode
.
Both function calls are needed to prevent breaking out. Using addslashes
prevents normal quotes ('
,"
) and rawurlencode
prevents already encoded quotes (%29
,%22
) to cause harm.
So final solution looks like this:
$splitVal = "#staticVal:";
$tmpArr = explode($splitVal, "dynamicVal#staticVal:dynamicVal'+alert(\"breakout\")+'");
$link = htmlspecialchars(sprintf("http://external-page.com/"."%s$splitVal%s", rawurlencode(addslashes($tmpArr[0])), rawurlencode(addslashes($tmpArr[1]))), ENT_QUOTES);
echo "<a href=\"javascript: window.open('$link')\">'Open URL'</a>";
Upvotes: 0
Reputation: 83692
You should use urlencode()
for this. Not on the whole string but on the dynamic parts only.
$link = sprintf('http://external-page.com/%s#staticVal:%s', urlencode('dynamicVal'), urlencode('dynamicVal'));
$var = "<a href=\"javascript: window.open('$link')\">'Open URL'</a>";
EDIT:
OK - I see your problem. I didn't realize that you insert the code into a JavaScript function call. You'll have to ensure that the JavaScript interpreter treats your link as a string argument to window.open()
:
$link = sprintf('http://external-page.com/%s#staticVal:%s', urlencode('dynamicVal'), urlencode('dynamicVal'));
$var = "<a href=\"javascript: window.open(".json_encode($link).")\">'Open URL'</a>";
Upvotes: 3