[nycphp-talk] question about javascript and avoiding XSS
Mitch Pirtle
mitch.pirtle at gmail.com
Sun Sep 12 21:40:31 EDT 2004
Here is a message posted in another list, I wanted to know what the
NYPHP gang thought. Also, curious to see if there are better
solutions that are done serverside (in PHP, of course!) or if we
really do need to rely on client-side checks?
<?php
/* noXSS (a)
* String a: Input that you want to print in a
*
* Description
* Use this function if you want to print user input as an argument in a HTML
* tag. Don't allow XSS JS attacks in your webapplication and use this function
* instead of using htmlspecialchars(), which doesn't protect you against the
* javascript: protocol.
*
* Return
* It will return false if
* the beginning of the input string contains 'javascript:', otherwise it will
* return
*
* Examples
* <?php
* print '<a href="'.$_GET['input'].'>link</a>';
* ?>
*
* input: 'javascript:alert()' output: bool false
* input: 'JAVAscript:alert()' output: bool false
* input: ' javascript:alert()' output: bool false
* input: ' javascript:alert()' output: bool false
* input: 'javascript:alert()' output: bool false
* input: ' Javascript:alert()' output: bool false
* input: 'test <a href="#">' output: test <a
href="#">yo
* input: '"><script>alert()</script><"' output:
"><script>alert()</script><"
* input: "'><script>alert()</script><'" output:
'><script>alert()</script><'
*
* Copyright by Sijmen Ruwhof. Use these function for free if this
statement is kept.
*/
function noXSS ($input)
{
# convert all input charakters to lowercase and convert ascii
encoded charakters to normal charakters
$inputTmp = trim(asciiDecode(strtolower($input)));
# check if the user wants to execute javascript
if (substr($inputTmp, 0, 11) == 'javascript:') {
trigger_error("Someone tried to exploit our UBB system!
Original input: '$input'", E_USER_WARNING);
return false;
}
# replace: <, >, &, ", ' to ascii encoded values
return htmlspecialchars($input, ENT_QUOTES);
}
/* asciiDecode (a)
* String a: Text string
*
* Description
* All ASCII codes will be decoded in their represented value.
*/
function asciiDecode($input)
{
# get all ASCII encoded values
preg_match_all("(&#([0-9]{1,3});)", $input, $matches);
$asciiCodes = array_unique($matches[1]);
# replace them with their representing value
foreach ($asciiCodes as $asciiNr)
$input = str_replace("&#$asciiNr;", chr($asciiNr), $input);
return $input;
}
?>
The only thing it doen't stop is:
<?php
// script.php
print '<a href="#" onmouseover="'.noXSS($_GET['x']).'">link</a>';
?>
-----------------------------------------------------------------------------------------------------------
Is there a better way to do this?
-- Mitch
More information about the talk
mailing list