pastebin - collaborative debugging

pastebin is a collaborative debugging tool allowing you to share and modify code snippets while chatting on IRC, IM or a message board.

This site is developed to XHTML and CSS2 W3C standards. If you see this paragraph, your browser does not support those standards and you need to upgrade. Visit WaSP for a variety of options.

php private pastebin - collaborative debugging tool What's a private pastebin?


Posted by Master on Thu 9 Jul 13:14 (modification of post by Master view diff)
report abuse | View followups from Master | download | new post

  1.         function xss_clean($str) {
  2.                 /*
  3.                  * Remove Null Characters
  4.                  *
  5.                  * This prevents sandwiching null characters
  6.                  * between ascii characters, like Java\0script.
  7.                  */
  8.                 $str = preg_replace('/\0+/', '', $str);
  9.                 $str = preg_replace('/(\\\\0)+/', '', $str);
  10.                
  11.                 /*
  12.                  * Validate standard character entities
  13.                  *
  14.                  * Add a semicolon if missing.  We do this to enable
  15.                  * the conversion of entities to ASCII later.
  16.                  */
  17.                 $str = preg_replace('#(&\#?[0-9a-z]+)[\x00-\x20]*;?#i', "\\1;", $str);
  18.                
  19.                 /*
  20.                  * Validate UTF16 two byte encoding (x00)
  21.                  *
  22.                  * Just as above, adds a semicolon if missing.
  23.                  */
  24.                 $str = preg_replace('#(&\#x?)([0-9A-F]+);?#i', "\\1\\2;", $str);
  25.                
  26.                 /*
  27.                  * URL Decode
  28.                  *
  29.                  * Just in case stuff like this is submitted:
  30.                  * <a href="http://%77%77%77%2E%67%6F%6F%67%6C%65%2E%63%6F%6D">Google</a>
  31.                  * Note: Use rawurldecode() so it does not remove plus signs
  32.                  */
  33.                 $str = rawurldecode($str);
  34.                
  35.                 /*
  36.                  * Convert character entities to ASCII
  37.                  *
  38.                  * This permits our tests below to work reliably.
  39.                  * We only convert entities that are within tags since
  40.                  * these are the ones that will pose security problems.
  41.                  */
  42.                
  43.                 $str = preg_replace_callback("/[a-z]+=([\'\"]).*?\\1/si", array($this, '_attribute_conversion'), $str);
  44.                
  45.                 $str = preg_replace_callback("/<([\w]+)[^>]*>/si", array($this, '_html_entity_decode_callback'), $str);
  46.                
  47.                 /*
  48.                
  49.                 Old Code that when modified to use preg_replace()'s above became more efficient memory-wise
  50.                
  51.                 if (preg_match_all("/[a-z]+=([\'\"]).*?\\1/si", $str, $matches))                {        
  52.                         for ($i = 0; $i < count($matches[0]); $i++)                     {
  53.                                 if (stristr($matches[0][$i], '>'))                              {
  54.                                         $str = str_replace(     $matches['0'][$i],      str_replace('>', '&lt;', $matches[0][$i]),              $str);
  55.                                 }
  56.                         }
  57.                 }
  58.                  
  59.     if (preg_match_all("/<([\w]+)[^>]*>/si", $str, $matches))    {        
  60.                         for ($i = 0; $i < count($matches[0]); $i++)                     {
  61.                                 $str = str_replace($matches[0][$i], $this->_html_entity_decode($matches[0][$i], $charset),      $str);
  62.                         }
  63.                 }
  64.                 */
  65.                
  66.                 /*
  67.                  * Convert all tabs to spaces
  68.                  *
  69.                  * This prevents strings like this: ja  vascript
  70.                  * NOTE: we deal with spaces between characters later.
  71.                  * NOTE: preg_replace was found to be amazingly slow here on large blocks of data,
  72.                  * so we use str_replace.
  73.                  */
  74.                
  75.                 $str = str_replace("\t", " ", $str);
  76.                
  77.                 /*
  78.                  * Not Allowed Under Any Conditions
  79.                  */
  80.                 $bad = array(
  81.                         'document.cookie' => '[removed]',
  82.                         'document.write' => '[removed]',
  83.                         '.parentNode' => '[removed]',
  84.                         '.innerHTML' => '[removed]',
  85.                         'window.location' => '[removed]',
  86.                         '-moz-binding' => '[removed]',
  87.                         '<!--' => '&lt;!--',
  88.                         '-->' => '--&gt;',
  89.                         '<!CDATA[' => '&lt;![CDATA['
  90.                 );
  91.                 foreach ($bad as $key=>$val) {
  92.                         $str = str_replace($key, $val, $str);
  93.                 }
  94.                
  95.                 $bad = array(
  96.                         "javascript\s*:" => '[removed]',
  97.                         "expression\s*\(" => '[removed]', // CSS and IE
  98.                         "Redirect\s+302" => '[removed]'
  99.                 );
  100.                 foreach ($bad as $key=>$val) {
  101.                         $str = preg_replace("#" . $key . "#i", $val, $str);
  102.                 }
  103.                
  104.                 /*
  105.                  * Makes PHP tags safe
  106.                  *
  107.                  *  Note: XML tags are inadvertently replaced too:
  108.                  *      <?xml
  109.                  * But it doesn't seem to pose a problem.
  110.                  */
  111.                 $str = str_replace(array('<?php', '<?PHP', '<?', '?' . '>'), array('&lt;?php', '&lt;?PHP', '&lt;?', '?&gt;'), $str);
  112.                
  113.                 /*
  114.                  * Compact any exploded words
  115.                  *
  116.                  * This corrects words like:  j a v a s c r i p t
  117.                  * These words are compacted back to their correct state.
  118.                  */
  119.                 $words = array('javascript', 'expression', 'vbscript', 'script', 'applet', 'alert', 'document', 'write', 'cookie', 'window');
  120.                 foreach ($words as $word) {
  121.                         $temp = '';
  122.                         for($i = 0; $i < strlen($word); $i++) {
  123.                                 $temp .= substr($word, $i, 1) . "\s*";
  124.                         }
  125.                        
  126.                         // We only want to do this when it is followed by a non-word character
  127.                         // That way valid stuff like "dealer to" does not become "dealerto"
  128.                         $str = preg_replace('#(' . substr($temp, 0, -3) . ')(\W)#ise', "preg_replace('/\s+/s', '', '\\1').'\\2'", $str);
  129.                 }
  130.                
  131.                 /*
  132.                  * Remove disallowed Javascript in links or img tags
  133.                  */
  134.                 do {
  135.                         $original = $str;
  136.                         if ((version_compare(PHP_VERSION, '5.0', '>=') === TRUE && stripos($str, '</a>') !== FALSE) or preg_match("/<\/a>/i", $str)) {
  137.                                 $str = preg_replace_callback("#<a.*?</a>#si", array($this, '_js_link_removal'), $str);
  138.                         }
  139.                         if ((version_compare(PHP_VERSION, '5.0', '>=') === TRUE && stripos($str, '<img') !== FALSE) or preg_match("/img/i", $str)) {
  140.                                 $str = preg_replace_callback("#<img.*?" . ">#si", array($this, '_js_img_removal'), $str);
  141.                         }
  142.                         if ((version_compare(PHP_VERSION, '5.0', '>=') === TRUE && (stripos($str, 'script') !== FALSE or stripos($str, 'xss') !== FALSE)) or preg_match("/(script|xss)/i", $str)) {
  143.                                 $str = preg_replace("#</*(script|xss).*?\>#si", "", $str);
  144.                         }
  145.                 } while ($original != $str);
  146.                
  147.                 unset($original);
  148.                
  149.                 /*
  150.                  * Remove JavaScript Event Handlers
  151.                  *
  152.                  * Note: This code is a little blunt.  It removes the event handler and anything up to the closing >,
  153.                  * but it's unlikely to be a problem.
  154.                  */
  155.                 $event_handlers = array('onblur', 'onchange', 'onclick', 'onfocus', 'onload', 'onmouseover', 'onmouseup', 'onmousedown', 'onselect', 'onsubmit', 'onunload', 'onkeypress', 'onkeydown', 'onkeyup', 'onresize', 'xmlns');
  156.                 $str = preg_replace("#<([^>]+)(" . implode('|', $event_handlers) . ")([^>]*)>#iU", "&lt;\\1\\2\\3&gt;", $str);
  157.                
  158.                 /*
  159.                  * Sanitize naughty HTML elements
  160.                  *
  161.                  * If a tag containing any of the words in the list
  162.                  * below is found, the tag gets converted to entities.
  163.                  *
  164.                  * So this: <blink>
  165.                  * Becomes: &lt;blink&gt;
  166.                  */
  167.                 $str = preg_replace('#<(/*\s*)(alert|applet|basefont|base|behavior|bgsound|blink|body|embed|expression|form|frameset|frame|head|html|ilayer|iframe|input|layer|link|meta|object|plaintext|style|script|textarea|title|xml|xss)([^>]*)>#is', "&lt;\\1\\2\\3&gt;", $str);
  168.                
  169.                 /*
  170.                  * Sanitize naughty scripting elements
  171.                  *
  172.                  * Similar to above, only instead of looking for tags it looks for PHP and JavaScript commands
  173.                  * that are disallowed.  Rather than removing the code, it simply converts the parenthesis to entities
  174.                  * rendering the code un-executable.
  175.                  *
  176.                  * For example: eval('some code')
  177.                  * Becomes:             eval&#40;'some code'&#41;
  178.                  */
  179.                 $str = preg_replace('#(alert|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si', "\\1\\2&#40;\\3&#41;", $str);
  180.                
  181.                 /*
  182.                  * Final clean up
  183.                  *
  184.                  * This adds a bit of extra precaution in case something got through the above filters
  185.                  */
  186.                 $bad = array(
  187.                         'document.cookie' => '[removed]',
  188.                         'document.write' => '[removed]',
  189.                         '.parentNode' => '[removed]',
  190.                         '.innerHTML' => '[removed]',
  191.                         'window.location' => '[removed]',
  192.                         '-moz-binding' => '[removed]',
  193.                         '<!--' => '&lt;!--', '-->' => '--&gt;',
  194.                         '<!CDATA[' => '&lt;![CDATA['
  195.                 );
  196.                 foreach ($bad as $key=>$val) {
  197.                         $str = str_replace($key, $val, $str);
  198.                 }
  199.                
  200.                 $bad = array(
  201.                         "javascript\s*:" => '[removed]',
  202.                         "expression\s*\(" => '[removed]', // CSS and IE
  203.                         "Redirect\s+302" => '[removed]'
  204.                 );
  205.                 foreach ($bad as $key=>$val) {
  206.                         $str = preg_replace("#" . $key . "#i", $val, $str);
  207.                 }
  208.                
  209.                 log_message('debug', "XSS Filtering completed");
  210.                 return $str;
  211.         }

Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:

To highlight particular lines, prefix each line with @@


Remember me so that I can delete my post