Tapjacking is an attack technique which involves displaying overlay window on top of some security sensitive content and tricking user into unwittingly tapping some UI elements.
It was used in a screen access vulnerability described in the previous post.
In Gingerbread a touch filtering mechanism got introduced and documented in Security section of
View class documentation. This mechanism relied on
MotionEvent.FLAG_WINDOW_IS_OBSCURED flag which has the following documentation.
This flag indicates that the window that received this motion event is partly or wholly obscured by another visible window above it. This flag is set to true even if the event did not directly pass through the obscured area. A security sensitive application can check this flag to identify situations in which a malicious application may have covered up part of its content for the purpose of misleading the user or hijacking touches. An appropriate response might be to drop the suspect touches or to take additional precautions to confirm the user’s actual intent.
This is a decent design. It could be more flexible e.g. detect view level overlapping instead of windows overlapping, or allowing for custom filtering without need to extend the
View class but it was OK for a start.
Unfortunately the initial implementation as well as the current production code doesn’t conform to the documentation. Apparently somewhere at C++/Java boundary the meaning of the
MotionEvent flag got lost and it’s being set only if the touched point is obscured.
It’s surprising that for four years no one noticed this. Or perhaps it got noticed, reported and is waiting in a long secret queue of Low severity security bugs…
Initially I thought of submitting a simple fix which would get the actual behavior in line with the documentation. Then I realized that this is likely to cause compatibility issues as the apps using touch filtering feature are tested using the current implementation and may not be compatible with the more strict filtering. This lead me to the conclusion that only a documentation should be updated for the current
MotionEvent flag and a new flag matching the old documentation should be introduced. That way, the behavior of existing apps won’t change but developers will have a chance to enable stricter touch filtering.