2018-12-09
Firefox, WebExtensions, and Content Security Policies
Today, Grant Taylor left some comments on entries here (eg yesterday's). As I often do for people who leave comments here who include their home page, I went and visited Taylor's home page in my usual Firefox browser, then when I was done I made my usual and automatic Foxygestures gesture to close the page. Except that this time, nothing happened (well, Firefox's right mouse button popup menu eventually came up when I released the mouse button).
In the old days of Firefox's original XUL/XPCOM-based addons, while it was true that you could write addons mostly or entirely in Javascript, that was sort of a side effect of the fact that a significant amount of Firefox itself was implemented in Javascript. There was not really a special API or language environment that was designed just for addons, as far as I know; instead your addon was in large part a bit of Firefox that wasn't part of its main code. As a result, it was generally the case that anything Firefox could do, your addon could do, including to web pages.
Modern WebExtensions are completely different. They exist within a limited sandbox, and that sandbox is specifically Javascript based. It has its own limited set of APIs and for various reasons the APIs don't give WebExts unrestricted access to web pages. Instead WebExts must inject (Javascript) code into the web page's environment and then communicate with it. Because WebExtensions operate by injecting Javascript code into web page's environment, they (and their code) raises various questions about permissions.
(For instance, WebExtensions are not allowed to inject code into some web pages or otherwise touch them.)
Enter Content Security Policies. CSPs are a way for the web server to say what a web page is allowed to do, including where Javascript is allowed to be executed from, including if it's allowed to be executed from the page itself. In the old XUL/XPCOM world of addons, there was no question that addons had full access to a page even when the page had a CSP, because the browser itself had that access. In the new WebExtensions world where addons operate in part by injecting Javascript into the page's environment, there is a potential conflict between WebExtensions and a page with a restrictive CSP. Chrome (or if you prefer) Chromium specifically allows WebExtension injected Javascript to run, no matter what the page's CSP. Firefox currently blocks at least some things, per Firefox bug 1267027.
It's definitely clear that Foxygestures not working on Taylor's
site is because of the site's Content Security Policy headers (I
can make it work and not work by toggling security.csp.enable
),
but it's not clear why. Foxygestures is at least partly using content
scripts, which are supposed to not be subject to this issue if I'm
reading the Firefox bug correctly, but perhaps there's something
peculiar going on in what Foxygestures does in them. Firefox objects
to one part of the current Content-Security-Policy header, which
perhaps switches it to some extra-paranoid mode.
(I filed Foxygestures issue 283, if only so perhaps similar cases in the future have something to search for. There is Foxygestures issue 230, but in that the gestures still worked, the UI just had limitations.)
PS: This is where I wish for a Firefox addon that allows me to set or modify the CSP of web page(s) for debugging purposes, which I believe is at least possible in the WebExtensions API. Laboratory will do part of this but it doesn't seem to start from any existing site CSP, so the 'modifying' bit of my desires is at least awkward. mHeaderControl would let me block the CSPs of selected sites, at least in theory (I haven't tried it). It's a little bit surprising to me that you don't seem to be able to do this from within the Firefox developer tools, but perhaps the Firefox people thought this was a little bit too dangerous to provide.