Removing inline event handlers from the browser UI

367 views
Skip to first unread message

Tom Schuster

unread,
Sep 18, 2024, 5:13:42 AM9/18/24
to firef...@mozilla.org

Hello Firefox team!


As a joint effort of the Firefox and Security teams, we are trying to get rid of inline event handlers (e.g. onclick) from HTML code used in Firefox, primarily for everything in the parent process, including browser.xhtml.


In the past years PwnOwn exploits have leveraged the ability to dynamically add inline event handlers to gain JavaScript code execution, after exploiting the content process[1, 2]. To mitigate these attacks we want to give privileged pages a Content-Security-Policy that blocks inline event handlers from executing. In the recent months our efforts have reduced the number of inline event handlers (in browser.xhtml) from over 600 to under 200. The work is tracked in the meta bug 1890547.


We have done this by removing event handler attributes from HTML and moving them into the associated JavaScript files as addEventListener calls. There are still some unresolved issues, which we are able to address iteratively by starting small (e.g., with the “About Firefox” dialog). If you want to join the effort or are in the process of adding new event handlers, feel free to reach out.


To keep this momentum going, I would like to ask everyone landing new Firefox frontend code to avoid introducing new inline event handlers in HTML.


Thanks to everyone who helped with this effort

Tom Schuster

Nick Alexander

unread,
Sep 18, 2024, 12:47:56 PM9/18/24
to Tom Schuster, firef...@mozilla.org
Hi Tom,

This project sounds worthy, so I wonder: this ask seems lint-able, but I don't see a linting ticket in the dependency tree.  Is it not, in fact, lintable?  (Perhaps identifying parent process chrome code is equivalent to halting?)

Best,
Nick

Gijs Kruitbosch

unread,
Sep 19, 2024, 8:50:06 AM9/19/24
to Nick Alexander, Tom Schuster, firef...@mozilla.org
On 18/09/2024 12:47, 'Nick Alexander' via firef...@mozilla.org wrote:
This project sounds worthy, so I wonder: this ask seems lint-able, but I don't see a linting ticket in the dependency tree.  Is it not, in fact, lintable?  (Perhaps identifying parent process chrome code is equivalent to halting?)

We don't currently have significant linting infrastructure for XHTML. Especially the pre-processed XHTML dialect in our tree has proven to be trickier to lint than one might expect. Notably prettier doesn't actually work with XHTML and IIRC when we asked they were (understandably) not particularly interested in adding support.

Switching to non-X HTML is also non-trivial because of the prototype cache (formerly known as XUL cache) speed-ups we currently make use of (ie it would be a bunch of work to avoid a resulting performance regression). Plus of course we have a lot of markup so either way switching would further increase the scope of this already considerable project. :-)


We could try to do plaintext lint errors based on "dumb" substring matching of `onclick="` and `onclick='` and so on, though it feels a bit icky, and wouldn't allow fixup. And yes, isolating parent process chrome code would be a bit difficult to do, though I wouldn't mind having the linter rule for all non-test markup in the tree. Practically all in-content markup we ship should already have CSP in place (e.g. aboutNetError as a somewhat random example) and none of these handlers will exist there.

So adding linting is not a bad idea, but so far Tom has been providing patches so quickly, and given the HTML issues it seemed not super-easy to do it "neatly", that I hadn't thought it to be super valuable - the frontend team has been aware of this effort for a little while so I was not expecting a large number of "regressions" as such of people adding more of these.

Once windows have been purged of all the inline event handlers and we add CSP, then that will simply break any more such handlers so linting would be somewhat superfluous ("don't do this thing that doesn't work"). I suppose in theory linting (if appropriately editor-integrated, which I'm not sure we have a good way of doing for our plaintext linting) could still be a faster way for an author to realize _why_ an inline attribute wasn't working... so perhaps that means it is worth doing?

I defer somewhat to Tom's judgment here. But hopefully the context helps in terms of why we haven't "just" done this so far.

~ Gijs


Nick Alexander

unread,
Sep 19, 2024, 3:07:14 PM9/19/24
to Gijs Kruitbosch, Tom Schuster, firef...@mozilla.org
Gijs,

Thanks for a very informative answer.

I defer somewhat to Tom's judgment here. But hopefully the context helps in terms of why we haven't "just" done this so far.

It sounds like a lint isn't the right trade-off at this time, but I also defer to Tom's judgement.

Best,
Nick

Tom Schuster

unread,
Sep 20, 2024, 7:09:32 AM9/20/24
to Nick Alexander, Gijs Kruitbosch, firef...@mozilla.org
Thanks for the question. I don't have anything substantial to add to
Gijs answer. I am mostly driven by preventing inline event handlers
being added by exploit code, which linting wouldn't prevent. I would
rather spend my time on fixing the inline event handlers and adding
the CSP instead of trying to figure out how to make linting work for
XHTML.

Tom

Tom Schuster

unread,
Dec 31, 2024, 9:12:28 AM12/31/24
to firef...@mozilla.org, Tom Schuster, gijskru...@gmail.com, firef...@mozilla.org, Nick Alexander
Hello everyone!

We now removed all known (*) inline event handlers from code running in browser.xhtml. Yesterday, I landed a patch that blocks inline event handlers in debug builds (bug 1936336). The immediate next step is to disable inline event handlers in Nightly, combined with telemetry for CSP violations caused by previously unknown inline event handlers being blocked (1937080). After we are relatively certain that we found everything we will rollout the blocking behavior to release. A potential future project might be to get rid of all inline scripts.

Thanks to everyone who helped, especially with reviews (Gijs, mak, Standard8 and everyone else)!

Tom

* Thanks to the debug build changes Alice0775 White already found one more inline event handler: bug 1939553!
Reply all
Reply to author
Forward
0 new messages