Subversion Repositories php_utils

Rev

Rev 7 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. <?php
  2.  
  3. /*
  4.  * Anti XSS
  5.  * Copyright 2019 Daniel Marschall, ViaThinkSoft
  6.  *
  7.  * Licensed under the Apache License, Version 2.0 (the "License");
  8.  * you may not use this file except in compliance with the License.
  9.  * You may obtain a copy of the License at
  10.  *
  11.  *     http://www.apache.org/licenses/LICENSE-2.0
  12.  *
  13.  * Unless required by applicable law or agreed to in writing, software
  14.  * distributed under the License is distributed on an "AS IS" BASIS,
  15.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16.  * See the License for the specific language governing permissions and
  17.  * limitations under the License.
  18.  */
  19.  
  20. // This function prevents XSS, while still allowing the usage of HTML
  21. function anti_xss($str, $forbidden_tags=array('script','base','meta','link')) {
  22.         // Avoid usage of <script tags, but still allow tags that might
  23.         // have the prefix forbidden tagname as prefix (useful if you want
  24.         // to block other tags other than "script").
  25.         // $str = preg_replace('@<(/{0,1}script[^a-zA-Z])@i', '&lt;\\1', $str);
  26.         foreach ($forbidden_tags as $tagname) {
  27.                 if ($tagname == '*') {
  28.                         $str = str_replace('<', '&lt;', $str);
  29.                 } else {
  30.                         $str = preg_replace('@<(/{0,1}'.preg_quote($tagname,'@').'[^a-zA-Z])@i', '&lt;\\1', $str);
  31.                 }
  32.         }
  33.  
  34.         if (preg_grep('@^script$@i' , $forbidden_tags)) {
  35.                 // (1) Avoid stuff like a href="javascript:"
  36.                 $str = preg_replace('@(javascript|livescript|vbscript)\s*:@im', '\\1<!-- -->:', $str);
  37.  
  38.                 // (2) Avoid injection of JavaScript events like onload=, but still allow HTML tags that might start with <on...
  39.                 $str = preg_replace('@O([nN][a-zA-Z]+\s*=)@m', '&#x4F;\\1', $str);
  40.                 $str = preg_replace('@o([nN][a-zA-Z]+\s*=)@m', '&#x6F;\\1', $str);
  41.         }
  42.  
  43.         return $str;
  44. }
  45.  
  46.  
  47.  
  48. # Some testcases
  49. #echo anti_xss('hallo welt <script>alert(1)</script>');
  50. #echo anti_xss('<svg onload'."\n\n\r\t".'="alert(1)" src=""></svg><online></online> on august ONLINE');
  51. #echo anti_xss('<svg/onload=alert(\'XSS\')>');
  52. #echo '<a href="'.anti_xss('" onclick="alert(1)').'">Click me</a>';
  53. #echo anti_xss('<a href="">foo</a> <abc>xxx</abc>', array('a'));
  54. #echo anti_xss('<a href="">foo</a> <abc>xxx</abc>', array('*'));
  55. #echo anti_xss("<a href=\"JaVaScRiPt:alert('XSS')\">foobar</a> <pre>JavaScript: is cool</pre>");
  56. #echo anti_xss("<a href=\"JaVaScRiPt    :   alert('XSS')\">foobar</a> <pre>JavaScript  : is cool</pre>");
  57. #echo anti_xss("<a href=\"#\" onclick=\"vbscript:msgbox(\"XSS\")\">foobar</a> <pre>VbScript: is cool</pre>");
  58. #echo anti_xss('<META HTTP-EQUIV="Set-Cookie" Content="USERID=<SCRIPT>alert(\'XSS\')</SCRIPT>">');
  59.  
  60. # Currently we don't support these XSS vectors. But I am unsure if they work at all, in modern browsers
  61. #echo anti_xss('<BR SIZE="&{alert(\'XSS\')}">');
  62. #echo anti_xss('<a href="" onclick="java&#x0d;script:alert(\'1\')">bla</a>');
  63.  
  64. # Currently we are vulnerable to this vectors
  65. # (does not work with Chrome)
  66. #echo anti_xss('<EMBED SRC="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg==" type="image/svg+xml" AllowScriptAccess="always"></EMBED>');
  67. #echo anti_xss('<IMG STYLE="xss:expr/*XSS*/ession(alert(\'XSS\'))">'); // only IE
  68.  
  69. # TODO: find more vectors from cheat sheets
  70. # https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
  71.  
  72. /*
  73. if (isset($_POST['blabla'])) {
  74. echo anti_xss($_POST['blabla']);
  75. #echo $_POST['blabla'];
  76. } else {
  77.  
  78. echo '<form method="POST" action="anti_xss.php">';
  79. #echo '<textarea name="blabla">'.$_POST['blabla'].'</textarea>';
  80. echo '<textarea name="blabla"></textarea>';
  81. echo '<input type="submit">';
  82. echo '</form>';
  83. }
  84. */
  85.  
  86.