The curse of inverse strokejacking

 

This is the third interesting bug I had in my pipeline for a while. It's far less scary than the previous ones, but nevertheless, probably amusing enough.

A while ago, I posted a whimsical proof of concept for what I greatly enjoy calling strokejacking. The problem amounts to this: a rogue site can put an unrelated, third-party web application in a hidden frame - and then, by offering some seemingly legitimate functionality, entice the user to type in a body of text. As the user is typing, the attacker is free to examine key codes from within the onkeydown handler - and when desired, momentarily move focus to said hidden frame, causing the actual onkeypress event to be routed there instead. The trick essentially permits arbitrary, attacker-controlled input to be synthesized on the targeted site - possibly changing victim's privacy settings, setting up mail forwarding, or authorizing new users to access personal data.

The attack is arguably more interesting than your traditional, run-of-the-mill clickjacking, mostly because it allows for more complex interactions. Still, in most cases, it can be prevented the same way - with X-Frame-Options or with framebusting JavaScript - so no reason to panic, right?

 

Well, there's a twist: shortly after reporting this problem publicly several months ago, I realized that the attack scenario could be reversed. Consider a third-party gadget or an advertisement framed on a legitimate page, a pretty common pattern today. The frame is free to grab focus from the top-level document, as this operation is not governed by the same-origin policy. Normally, this causes the caret to disappear from where the user is expecting it to be - but by briefly giving up focus at strategically timed intervals, the appearance of a blinking cursor in the top-level document can be maintained. The rogue gadget can then read all the typed characters via onkeydown - and have onkeypress delivered to the top-level document, so that everything seems to be working as expected - with an extra copy of all the data silently delivered to the attacker.

 

A simple WebKit-specific proof of concept can be found here. The usual clickjacking defenses are not applicable in this scenario, for obvious reasons.