On 30 May Mozilla Foundation announced in its MFSA (Mozilla Foundation Security Advisory) 2007-16 a bug discovered by moz_bug_r_a4 able to bypass the same-origin policy using the addEventListener helper. Needless to say you can do really nasty things by exploiting this hole, ranging from xss attacks to keystrokes logging, with no same origin limitation. If you are impatient jump directly to the demo DOM Event Keylogger.
Mozilla contributor moz_bug_r_a4 demonstrated that the addEventListener method could be used to inject script into another site in violation of the browser's same-origin policy. This could be used to access or modify private or valuable information from that other site.
Official informations can be found in the Mozilla Foundation Security Advisory 2007-16 titled XSS using addEventListener, the original tickets are BUG 376987 (XSS using addEventListener)and BUG 377356 (Security checks in nsEventReceiverSH::AddEventListenerHelper can be circumvented).
An attacker can add an event listener to a target site. This allows an attacker to perform an XSS attack as well as to sniff keystrokes (like bug 18553).
When a JS code calls addEventListener method, the native addEventListener method is called through nsEventReceiverSH::AddEventListenerHelper unless the JS code uses Components.lookupMethod to get addEventListener method. And, nsEventReceiverSH::AddEventListenerHelper does not check whether caller can access a given event target. Thus, an attacker can add an event listener to a target site.
w = open("target site"); document.addEventListener.call(w, "keypress", x, true);And, when an event handler registered by the attacker is called, caller's context is the target site, and the attacker can control a string conversion of an event object. Thus, the attacker can perform an XSS attack.
The patch was not bulletproof and a second bug ticket followed from the same author.
Security checks in nsEventReceiverSH::AddEventListenerHelper can be circumvented in the following way.
<iframe src="target site"/> function X() {} X.prototype = frames[0]; var x = new X(); addEventListener.call(x, ...);
I have build a demo application DOM Event Keylogger, let me know if it works for you (Mozilla Firefox <= 2.0.0.3 should be fine). This is already patched on 2.0.0.4.
Update: There is a notable flaw in any implementation that make use of addEventListener "injection". Once the location of the iframe/open changes FF will throw an exception.
<mnemoc> ascii: after the frst search it doesn't log anymore <ascii> umh <ascii> true <ascii> uncaught exception: Permission denied to get property Window.addEventListener <ascii> it's not possible until you are on file:// <ascii> that is not the case of normal navigation on the interweb : ) <ascii> on file:// the helper can be reinjected as many times you want
Bye, Francesco `ascii` Ongaro.