Did a browser dom-checker run on Mozilla Firefox 3Beta 5...

Hi malware fighters,

How safe is the browser you run, go here and test:
http://lcamtuf.coredump.cx/dom_checker/
Every browser have some 14 weak spots, depending of developer’s choices for IE or FF or Safari,
I got this message half way:

“Unable to get ipc_write frame hash in response to EVAL(frames[0].name==‘dom-foo’) (1) in state 2
WARNING: Disabling side channel IPC, results may be less accurate!”

NoScript rules folks, it protects against them all, I found,

The results with NoScript temporarily not activated for FF 3Beta5 are:

CHECK FAILED : open() frame name lookup is possible!

CHECK FAILED : (third-party).frames[0] probe [value: [object Window]] is possible!

CHECK FAILED : (third-party).frames.length read [value: 2] is possible!

CHECK FAILED : (third-party).window[0] probe [value: [object Window]] is possible!

CHECK FAILED : (third-party).window.length read [value: 2] is possible!

CHECK FAILED : (third-party).history.forward(0) call is possible!

“you only get forward history when you press the back button- Note- pol”

CHECK FAILED : (third-party).length read [value: 2] is possible!

CHECK FAILED : (third-party).postMessage read [value: function postMessage() { [native code] }] is possible!

CHECK FAILED : (blank).frames.length read [value: 0] is possible!

CHECK FAILED : (blank).window.length read [value: 0] is possible!

CHECK FAILED : (blank).history.forward(0) call is possible!

CHECK FAILED : (blank).length read [value: 0] is possible!

CHECK FAILED : (blank).postMessage read [value: function postMessage() { [native code] }] is possible!

“A common concern of most Ajax applications has been around their resulting accessibility - Note: pol”

CHECK FAILED : (blank).location.replace(‘about:blank’) call is possible!

CHECK FAILED : (blank).document.open() call is possible!

“That is why you need a pop-up blocker - Note: pol”

CHECK FAILED : (blank).document.write(‘hi mom’) call is possible!

polonus

Safari 3.1.1 on Mac OS X 10.5.2
**NOTE: Safari only completed 5/16 of the tests and then gave an error below is what failed on what portion was run

CHECK FAILED : open() frame name lookup is possible!
CHECK FAILED : (third-party).frames[0] probe [value: [object DOMWindow]] is possible!
CHECK FAILED : (third-party).frames.length read [value: 2] is possible!
CHECK FAILED : (third-party).window[0] probe [value: [object DOMWindow]] is possible!
CHECK FAILED : (third-party).window.length read [value: 2] is possible!
CHECK FAILED : (third-party).history.forward(0) call is possible!
CHECK FAILED : (third-party).length read [value: 2] is possible!

Comparing my results below to polonus’ results from FIrefox 3 beta above it looks live FF3 has some good improvements

Firefox 2.0.0.14 on OS X 10.5.2
CHECK FAILED : open() frame name lookup is possible!
CHECK FAILED : (third-party).frames[0] probe [value: [object Window]] is possible!
CHECK FAILED : (third-party).frames.length read [value: 2] is possible!
CHECK FAILED : (third-party).window[0] probe [value: [object Window]] is possible!
CHECK FAILED : (third-party).window.length read [value: 2] is possible!
CHECK FAILED : delete (third-party).private_var probe is possible!
CHECK FAILED : (third-party).history.forward(0) call is possible!
CHECK FAILED : (third-party).Components read [value: [object nsXPCComponents]] is possible!
CHECK FAILED : (third-party).length read [value: 2] is possible!
CHECK FAILED : (third-party).document.location.onload write (via IPC) is possible!
CHECK FAILED : (third-party).document.location.onerror write (via IPC) is possible!
CHECK FAILED : (third-party).document.location.onchange write (via IPC) is possible!
CHECK FAILED : (third-party).document.location.onkeydown write (via IPC) is possible!
CHECK FAILED : (blank).history.forward(0) call is possible!
CHECK FAILED : (blank).Components read [value: [object nsXPCComponents]] is possible!
CHECK FAILED : (blank).length read [value: 0] is possible!
CHECK FAILED : (blank).document.location.onload write (via IPC) is possible!
CHECK FAILED : (blank).document.location.onerror write (via IPC) is possible!
CHECK FAILED : (blank).document.location.onchange write (via IPC) is possible!
CHECK FAILED : (blank).document.location.onkeydown write (via IPC) is possible!
CHECK FAILED : (blank).location.replace(‘about:blank’) call is possible!
CHECK FAILED : (blank).document.open() call is possible!
CHECK FAILED : (blank).document.write(‘hi mom’) call is possible!
CHECK FAILED : (third-party).document.open() call is possible!
CHECK FAILED : (third-party).document.write(‘hi mom’) call is possible!

Edited to add Firefox results and updated Safari Results

quite interesting

stock IE7 failed 14

CHECK FAILED : open() frame name lookup is possible! CHECK FAILED : for (e in (third-party)) iterator is possible! CHECK FAILED : (third-party).frames[0] probe [value: [object]] is possible! CHECK FAILED : (third-party).frames.length read [value: 2] is possible! CHECK FAILED : for (e in (third-party).frames) iterator is possible! CHECK FAILED : (third-party).length read [value: 2] is possible! CHECK FAILED : (third-party).window[0].name write (via IPC) is possible! CHECK FAILED : for (e in (blank)) iterator is possible! CHECK FAILED : (blank).length read [value: 0] is possible! CHECK FAILED : (blank).location.assign('about:blank') call is possible! CHECK FAILED : (blank).location.replace('about:blank') call is possible! CHECK FAILED : (blank).document.open() call is possible! CHECK FAILED : (blank).document.write('hi mom') call is possible! CHECK FAILED : file:/// frame is possible!

stock Maxthon 2.0.9 failed 13 (upon that IE7)

CHECK FAILED : open() frame name lookup is possible! CHECK FAILED : for (e in (third-party)) iterator is possible! CHECK FAILED : (third-party).frames[0] probe [value: [object]] is possible! CHECK FAILED : (third-party).frames.length read [value: 2] is possible! CHECK FAILED : for (e in (third-party).frames) iterator is possible! CHECK FAILED : (third-party).length read [value: 2] is possible! CHECK FAILED : (third-party).window[0].name write (via IPC) is possible! CHECK FAILED : for (e in (blank)) iterator is possible! CHECK FAILED : (blank).length read [value: 0] is possible! CHECK FAILED : (blank).location.replace('about:blank') call is possible! CHECK FAILED : (blank).document.open() call is possible! CHECK FAILED : (blank).document.write('hi mom') call is possible! CHECK FAILED : file:/// frame is possible!

stock Opera 9.27 failed 23

CHECK FAILED : open() frame name lookup is possible! CHECK FAILED : (third-party).window[0] probe [value: [object inaccessible]] is possible! CHECK FAILED : (third-party).window.length read [value: 2] is possible! CHECK FAILED : (third-party).document.clear() call is possible! CHECK FAILED : (third-party).window[0].name read [value: nf] is possible! CHECK FAILED : (third-party).window.name read [value: f] is possible! CHECK FAILED : (third-party).defaultStatus read [value: ] is possible! CHECK FAILED : (third-party).innerHeight read [value: 1] is possible! CHECK FAILED : (third-party).innerWidth read [value: 1] is possible! CHECK FAILED : (third-party).length read [value: 2] is possible! CHECK FAILED : (third-party).name read [value: f] is possible! CHECK FAILED : (third-party).outerHeight read [value: 910] is possible! CHECK FAILED : (third-party).outerWidth read [value: 1684] is possible! CHECK FAILED : (third-party).pageXOffset read [value: 0] is possible! CHECK FAILED : (third-party).pageYOffset read [value: 0] is possible! CHECK FAILED : (third-party).screenLeft read [value: 13] is possible! CHECK FAILED : (third-party).screenTop read [value: 508] is possible! CHECK FAILED : (third-party).screenX read [value: -4] is possible! CHECK FAILED : (third-party).screenY read [value: -30] is possible! CHECK FAILED : (third-party).status read [value: ] is possible! CHECK FAILED : (third-party).document.readyState read [value: complete] is possible! CHECK FAILED : document.getElementById('f').contentWindow.status read [value: ] is possi

Flock 1.1.2 fails 16

# CHECK FAILED : open() frame name lookup is possible! # CHECK FAILED : (third-party).frames[0] probe [value: [object Window]] is possible! # CHECK FAILED : (third-party).frames.length read [value: 2] is possible! # CHECK FAILED : (third-party).window[0] probe [value: [object Window]] is possible! # CHECK FAILED : (third-party).window.length read [value: 2] is possible! # CHECK FAILED : (third-party).history.forward(0) call is possible! # CHECK FAILED : (third-party).Components read [value: [object nsXPCComponents]] is possible! # CHECK FAILED : (third-party).length read [value: 2] is possible! # CHECK FAILED : (blank).history.forward(0) call is possible! # CHECK FAILED : (blank).Components read [value: [object nsXPCComponents]] is possible! # CHECK FAILED : (blank).length read [value: 0] is possible! # CHECK FAILED : (blank).location.replace('about:blank') call is possible! # CHECK FAILED : (blank).document.open() call is possible! # CHECK FAILED : (blank).document.write('hi mom') call is possible! # CHECK FAILED : (third-party).document.open() call is possible! # CHECK FAILED : (third-party).document.write('hi mom') call is possible!

FF 2.0.0.14 failed 25

# CHECK FAILED : open() frame name lookup is possible! # CHECK FAILED : (third-party).frames[0] probe [value: [object Window]] is possible! # CHECK FAILED : (third-party).frames.length read [value: 2] is possible! # CHECK FAILED : (third-party).window[0] probe [value: [object Window]] is possible! # CHECK FAILED : (third-party).window.length read [value: 2] is possible! # CHECK FAILED : delete (third-party).private_var probe is possible! # CHECK FAILED : (third-party).history.forward(0) call is possible! # CHECK FAILED : (third-party).Components read [value: [object nsXPCComponents]] is possible! # CHECK FAILED : (third-party).length read [value: 2] is possible! # CHECK FAILED : (third-party).document.location.onload write (via IPC) is possible! # CHECK FAILED : (third-party).document.location.onerror write (via IPC) is possible! # CHECK FAILED : (third-party).document.location.onchange write (via IPC) is possible! # CHECK FAILED : (third-party).document.location.onkeydown write (via IPC) is possible! # CHECK FAILED : (blank).history.forward(0) call is possible! # CHECK FAILED : (blank).Components read [value: [object nsXPCComponents]] is possible! # CHECK FAILED : (blank).length read [value: 0] is possible! # CHECK FAILED : (blank).document.location.onload write (via IPC) is possible! # CHECK FAILED : (blank).document.location.onerror write (via IPC) is possible! # CHECK FAILED : (blank).document.location.onchange write (via IPC) is possible! # CHECK FAILED : (blank).document.location.onkeydown write (via IPC) is possible! # CHECK FAILED : (blank).location.replace('about:blank') call is possible! # CHECK FAILED : (blank).document.open() call is possible! # CHECK FAILED : (blank).document.write('hi mom') call is possible! # CHECK FAILED : (third-party).document.open() call is possible! # CHECK FAILED : (third-party).document.write('hi mom') call is possible!

Hi Dwarden,

An effective defense can be replacing the original script part with the following code, which verifies that the string written to the HTML page consists of alphanumeric characters only:

 <SCRIPT>
  var pos=document.URL.indexOf("name=")+5;
  var name=document.URL.substring(pos,document.URL.length);
  if (name.match(/^[a-zA-Z0-9]$/))
  {
       document.write(name);
  }
  else
  {
        window.alert("Security error");
  }
  
  </SCRIPT>

In the above example, the situation is very simple, in more complex scenarios wherein the security checks are less than perfect, this may come to play.
Such functionality can (and perhaps should) be provided through a generic library for sanitation of data (i.e. a set of Javascript functions that perform input validation and/or sanitation). The downside is that the security logic is exposed to the attackers - it is embedded in the HTML code. This makes it easier to understand and to attack it,


SecFilterEngine On
SecFilterScanPOST On
SecFilter "<(.|\n)+>"
Input fn="insert-filter"
 method="POST"
filter="sed-request"
 sed="s/(<|%3c)/\\&lt;/gi" 
 sed="s/(>|%3e)/\\&gt;/gi"
function RemoveBad(strTemp) { 
    strTemp = strTemp.replace(/\<|\>|\"|\'|\%|\;|\(|\)|\&|\+|\-/g,""); 
    return strTemp;
} 

<% Session("StoredPreference") = RemoveBad(Request.Cookies("UserColor"));
         var TempStr = RemoveBad(Request.QueryString("UserName"));

function RemoveBad(strTemp) { 
    strTemp = strTemp.replace	
(';alert(String.fromCharCode(88,83,83))//\';alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//\";alert(String.fromCharCode(88,83,83))//--></SCRIPT>">'><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>

'';!--"<XSS>=&{()}

<IMG SRC=JaVaScRiPt:alert('XSS')>

<IMG SRC=javascript:alert(&quot;XSS&quot;)>

<IMG SRC=`javascript:alert("RSnake says, 'XSS'")`>

<IMG """><SCRIPT>alert("XSS")</SCRIPT>">

<IMG SRC
=javascript:alert(String.fromCharCode(88,83,83))>

<IMG SRC=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#39;&#88;&#83;&#83;&#39;&#41;>

<IMG SRC="jav	ascript:alert('XSS');">

perl -e 'print "<IMG SRC=java\0script:alert(\"XSS\")>";' > out

<BODY onload!#$%&()*~+-_.,:;?@[/|\]^`=alert("XSS")>

</TITLE><SCRIPT>alert("XSS");</SCRIPT>

<IMG SRC='vbscript:msgbox("XSS")'>

<A HREF="http://%77%77%77%2E%67%6F%6F%67%6C%65%2E%63%6F%6D">XSS</A>)
return strTemp;
} <script type="text/javascript">
  function displayName() {
    var description = document.getElementById("description").value;
    var display = document.getElementById("display");
    description = description .replace(/</g, "&lt;").replace(/>/g, "&gt;");
    display.innerHTML = description;
  } 
</script>description.replace(/[\"\'][\s]*javascript:(.*)[\"\']/g, "\"\"");
    description = description.replace(/script(.*)/g, "");    
    description = description.replace(/eval\((.*)\)/g, "");
    description = description.replaceAll("<", "&lt;").replaceAll(">", "&gt;");
    description = description.replaceAll("eval\\((.*)\\)", "");
    description = description.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
    description = description.replaceAll("script", "");
function RemoveXSS($val) {
   // remove all non-printable characters. CR(0a) and LF(0b) and TAB(9) are allowed
   // this prevents some character re-spacing such as <java\0script>
   // note that you have to handle splits with \n, \r, and \t later since they *are* allowed in some inputs
   $val = preg_replace('/([\x00-\x08][\x0b-\x0c][\x0e-\x20])/', '', $val);
   
   // straight replacements, the user should never need these since they're normal characters
   // this prevents like <IMG SRC=&#X40&#X61&#X76&#X61&#X73&#X63&#X72&#X69&#X70&#X74&#X3A&#X61&#X6C&#X65&#X72&#X74&#X28&#X27&#X58&#X53&#X53&#X27&#X29>
   $search = 'abcdefghijklmnopqrstuvwxyz';
   $search .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
   $search .= '1234567890!@#$%^&*()';
   $search .= '~`";:?+/={}[]-_|\'\\';
   for ($i = 0; $i < strlen($search); $i++) {
      // ;? matches the ;, which is optional
      // 0{0,7} matches any padded zeros, which are optional and go up to 8 chars
   
      // &#x0040 @ search for the hex values
      $val = preg_replace('/(&#[x|X]0{0,8}'.dechex(ord($search[$i])).';?)/i', $search[$i], $val); // with a ;
      // &#00064 @ 0{0,7} matches '0' zero to seven times
      $val = preg_replace('/(&#0{0,8}'.ord($search[$i]).';?)/', $search[$i], $val); // with a ;
   }
   
   // now the only remaining whitespace attacks are \t, \n, and \r
   $ra1 = Array('javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'link', 'style', 'script', 'embed', 'object', 'iframe', 'frame', 'frameset', 'ilayer', 'layer', 'bgsound', 'title', 'base');
   $ra2 = Array('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterchange', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete', 'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart', 'onrowenter', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload');
   $ra = array_merge($ra1, $ra2);
   
   $found = true; // keep replacing as long as the previous round replaced something
   while ($found == true) {
      $val_before = $val;
      for ($i = 0; $i < sizeof($ra); $i++) {
         $pattern = '/';
         for ($j = 0; $j < strlen($ra[$i]); $j++) {
            if ($j > 0) {
               $pattern .= '(';
               $pattern .= '(&#[x|X]0{0,8}([9][a][b]);?)?';
               $pattern .= '|(&#0{0,8}([9][10][13]);?)?';
               $pattern .= ')?';
            }
            $pattern .= $ra[$i][$j];
         }
         $pattern .= '/i';
         $replacement = substr($ra[$i], 0, 2).'<x>'.substr($ra[$i], 2); // add in <> to nerf the tag
         $val = preg_replace($pattern, $replacement, $val); // filter out the hex tags
         if ($val_before == $val) {
            // no replacements were made, so exit the loop
            $found = false;
         }
      }
   }
   return $val;
}

Code courtesy of http://sla.ckers.org/forum/

polonus

Hi testers,

The funny thing is for the Browzar 1.5.0.0. browser shell only the following 14 failed:
CHECK FAILED : open() frame name lookup is possible!
CHECK FAILED : for (e in (third-party)) iterator is possible!
CHECK FAILED : (third-party).frames[0] probe [value: [object]] is possible!
CHECK FAILED : (third-party).frames.length read [value: 2] is possible!
CHECK FAILED : for (e in (third-party).frames) iterator is possible!
CHECK FAILED : (third-party).length read [value: 2] is possible!
CHECK FAILED : (third-party).window[0].name write (via IPC) is possible!
CHECK FAILED : for (e in (blank)) iterator is possible!
CHECK FAILED : (blank).length read [value: 0] is possible!
CHECK FAILED : (blank).location.assign(‘about:blank’) call is possible!
CHECK FAILED : (blank).location.replace(‘about:blank’) call is possible!
CHECK FAILED : (blank).document.open() call is possible!
CHECK FAILED : (blank).document.write(‘hi mom’) call is possible!
CHECK FAILED : file:/// frame is possible!

polonus

Hi malware fighters,

Less even in another IE7 shell , named TheWorld Browser 2.0 Final Version: 2.0.6.6
Copyright Phoenix Studio(2004-2007)
13 failed:
CHECK FAILED : open() frame name lookup is possible!
CHECK FAILED : for (e in (third-party)) iterator is possible!
CHECK FAILED : (third-party).frames[0] probe [value: [object]] is possible!
CHECK FAILED : (third-party).frames.length read [value: 2] is possible!
CHECK FAILED : for (e in (third-party).frames) iterator is possible!
CHECK FAILED : (third-party).length read [value: 2] is possible!
CHECK FAILED : (third-party).window[0].name write (via IPC) is possible!
CHECK FAILED : for (e in (blank)) iterator is possible!
CHECK FAILED : (blank).length read [value: 0] is possible!
CHECK FAILED : (blank).location.replace(‘about:blank’) call is possible!
CHECK FAILED : (blank).document.open() call is possible!
CHECK FAILED : (blank).document.write(‘hi mom’) call is possible!
CHECK FAILED : file:/// frame is possible!

polonus