November 06, 2008

NoEmbed - no click?

Intro

Mozilla once implemented an non standard tag for markup to display if there's no appropriate player for the embedded content. Like noframes, noembed and noscript. This conditionally displayed tag is not very well known and doesn't reside on too many blacklists. Nevertheless all browsers but IE treat this element as a DIV or even HTML tag and display it when outfitted with styles. Same for noframes - might well be the usually wrong DTD - but at least not for noscript.

Code

Here's an example of artificially bloated noembed and noframes tags.

<html>
<head>
<style>
 #noframes, #noembed {
     background: red;
     display: block;
     color: red;
     margin: 10px;
 }
</style>
</head>
<body>
 <noframes id="noframes" onclick="alert(this)">
     X
 </noframes>
 <noembed id="noembed" onclick="eval(this.innerHTML)">
     alert(this)
 </noembed>
</body>
</html>

On the other hand it's not really surprising. Most browsers handle unknown tags like inline elements or in case of Firefox HTMLUnknownElement. This means one can bind most interaction dependent event, create huge overlays via in-line styles etc.

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
 <do_what_now onclick="eval(this.innerHTML)">alert(this)</do_what_now>
</body>
</html>

Noframes and noembed are of course no unknown tags by the way. The WASC Script Mapping Project claims there are no event handlers for these tags available but the code examples prove this faulty. No offense though - this tool is still a very useful and valuable resource.

Conclusion

Not much to say. The only two browsers behaving reasonably are Opera and most versions of IE. Webkit and Chrome are way too tolerant again. At least the before mentioned examples prove - as well as the following - that blacklists for HTML filtering are useless due to the fact that most browsers don't use a white-list before rendering. But let's not be too harsh - none of the tested browsers rendered an IFrame wrapped in noscript or even noframes.

<y? style = "
      top:10px;
      width:99%;
      height:99%;
      position:absolute;
      background:red;
      display:block;
  "
  onmouseover = "with(this.style)display='none'"
  onmouseout  = "with(this.style)display='block',background='white'">
&nbsp;
</y?>