Open pes10k opened 3 weeks ago
as an example of why this matters for a scriptlet, consider the following:
a filter list has the rule site.example##+js(nowebrtc)
, indicating that a scriptlet should be run on site.example
to prevent site.example
from accessing WebRTC (e.g., window.RTCPeerConnection
).
However, site.example
can then re-gain access to WebRTC APIs w/ a local frame (since scriptlets aren't run in local frames).
// this will be blocked / NOOP bc of this scriptlet
// https://github.com/gorhill/uBlock/blob/26b2ab8bb5fc572a64e75d58f8d4d6388d9909c5/assets/resources/scriptlets.js#L3040
const connection1 = new RTCPeerConnection()
// this will noop bc of the scriplet. No connection is created
connection1.createOffer()
const frameElm = document.createElement('iframe')
frameElm.src = 'about:blank'
const originalRTCPeerConnection = frameElm.contentWindow.RTCPeerConnection
const connection2 = new originalRTCPeerConnection()
// this will NOT noop, the site has regained access to the WebRTC API
connection2.createOffer()
We will need to do this check for local
schemes i.e. about
, blob
or (not data: since it gets a new empty origin) (https://fetch.spec.whatwg.org/#local-scheme)data
@ShivanKaul you should still check data, and make sure that parent frames can't access window
on the child frame (since they could circumvent scriptlets that way, even if they can't regain access to storage)
Description
Brave iOS mishandles some aspects of content filtering in local frames (e.g., frames with the url
about:blank
, or otherwise inherit the security origin of the parent frame, w/o having that origin in the frame's URL)first-party
orthird-party
filtersThe root reason is that checks for the frame's origin are done using
window.location.href
, which will be something likeabout:blank
, even though the frame's code is running with access to cookies/etc for the parent frame.This is also a concern for scriptlets, which also aren't executed in iOS in local frames. This is a problem bc the parent frame can access the global object for the child local frame to re-obtain access to unmodified JS structures and prototypes (and so circumvent the scriptlets)
Steps to reproduce
The below is a general example of the vulnerability. The different issues discussed above can all be exploited through slightly different means.
This filter list rule should block all first-party image requests on
site.example
:site.example$first-party,img
However, if you run the following JS in a page hosted from
site.example
, the image request will not be blockedThe casue
Actual result
the image request to
//site.example/image.png
will not be blocked.Expected result
the image request to
//site.example/image.png
shoud be blocked.Reproduces how often
Easily reproduced
Brave version
all versions
Device/iOS version
all versions
Affected browser versions
Reproducibility
Miscellaneous information
Feel free to contact @pes10k with any questions about this. These vulnerabilities were the result of an ongoing research project between Brave an the University of California, San Diego