CSP is really great at plugging these kinds of security holes, but it flummoxes me that most developers and designers don't take them seriously enough to implement properly (styles must only be set though <link>, and JS likewise exists only in external files). Doing any styling or scripting inline should be frowned upon as hard as table-based layouts.
> Doing any styling or scripting inline should be frowned upon as hard as table-based layouts.
I strongly disagree: inlining your entire CSS and JS is absurdly good for performance, up to a surprisingly large size. If you have less than 100KB of JS and CSS (which almost every content site should be able to, most trivially, and almost all should aim to), there’s simply no question about it, I would recommend deploying with only inline styles and scripts. The threshold where it becomes more subjective is, for most target audiences, possibly over half a megabyte by now.
Seriously, it’s ridiculous just how good inlining everything is for performance, whether for first or subsequent page load; especially when you have hundreds of milliseconds of latency to the server, but even when you’re nearby. Local caches can be bafflingly slow, and letting the browser just execute it all in one go without even needing to look for a file has huge benefits.
It’s also a lot more robust. Fetching external resources is much more fragile than people tend to imagine.
Honest question: I don't understand how forbidding inline scripts and style improves security. Also it would be a serious inconvenience to the way we distribute some of our software right now lol
> it flummoxes me that most developers and designers don't take them seriously enough to implement properly (styles must only be set though <link>, and JS likewise exists only in external files). Doing any styling or scripting inline should be frowned upon as hard as table-based layouts.
At our place we do abide by those rules, but we also use 3rd party components like Telerik/Kendo which require both unsafe-inline for scripting and styling. Sometimes you have no choice laxing your security policy.
> should be frowned upon as hard as table-based layouts
I absolutely agree with you. I've been very very keen on CSP for a long time, it feels SO good to know that that vector for exploiting vulnerabilities is plugged.
One thing that's very noticeable: It seems to block/break -a lot- of web extensions. Basically every error I see in Sentry is of the form of "X.js blocked" or "random script eval blocked", stuff that's all extension-related.
Why? If you're the content owner, you should be able to. If you factor out inline code, you will likely just trust your own other domain. When everything is a cdn this can lead to less security not more.
Do you mean people should be banned from inlining Google Analytics or Meta Pixel or Index Now or whatever, which makes a bunch of XHRs to who knows where? Absolutely!
But nerfing your own page performance just to make everything CSP-compliant is a fool's errand.
One of the possible workarounds would be to just remove the damn header before it causes any further inconvenience. I think they do allow `webRequest` API usage in the store, don't they?
This is an entire class of vulnerabilities that would've never been possible with XUL, is that correct?
I appreciate they had to move for other reasons but I also really don't like the idea that the DevTools and browser chrome itself now has all of the same security issues/considerations as anything else "web" does. It was bad with Electron (XSS suddenly becoming an RCE) and makes me pretty nervous here too :(
I am surprised there is no policy that would allow inline event handlers set in the initial payload (or stuff emitted by document.write), but neuter any done after initial render by `….setAttribute('on…', …)`.
That would keep "static form" helpers still functional, but disable (malicious) runtime templating.
I can't help but wonder if this HTML-based setup is actually more trouble than it's worth. It seems there's a very complex ecosystem in there that is hard to reason about in this way, and it's a top-level requirement for a browser to sandbox the various bits of code being executed from a web page.
Obviously hard to say what those tradeoffs are worth, but I'd be a bit nervous about it. The work covered by this post is a good thing, of course!
Do this, and then use Firefox's profiles to have weaker instances without these configs.
Why? Some sites implement then break this, sadly.
I have extremely locked down instances for banks and so on. On Linux I have an icon which lets me easily launch those extra profiles.
I also use user.js, which means I can just drop in changes, and write comments for each config line, and keep it version controlled too. Great for cloning to other devices too.
CSP is a soothing cream but is most usually easily bypassed by other simple attacks relying on poor DOM management and security - to this day my team has never found so many web vulnerabilities just going into the DOM...
Mozilla's finally realizing what my paranoid uncle has been shouting for years: "They're coming for your browser UI!"Jokes aside, it's pretty cool seeing them implement CSP in the front-end. Kind of like putting a security guard at the entrance of a bank that already has 50 guards inside. But hey, that 51st guard might be the one who catches the bad guy!The separation between privileged and unprivileged processes reminds me of my relationship with coffee - I know I shouldn't let it access my system too often, but somehow it always finds a way in.What's actually impressive is how Firefox keeps evolving despite being around forever (in internet years). Most of us would have given up and said "eh, good enough" years ago. Next thing you know they'll be securing the about:config page with a pop quiz on quantum physics.
theandrewbailey|10 months ago
chrismorgan|10 months ago
I strongly disagree: inlining your entire CSS and JS is absurdly good for performance, up to a surprisingly large size. If you have less than 100KB of JS and CSS (which almost every content site should be able to, most trivially, and almost all should aim to), there’s simply no question about it, I would recommend deploying with only inline styles and scripts. The threshold where it becomes more subjective is, for most target audiences, possibly over half a megabyte by now.
Seriously, it’s ridiculous just how good inlining everything is for performance, whether for first or subsequent page load; especially when you have hundreds of milliseconds of latency to the server, but even when you’re nearby. Local caches can be bafflingly slow, and letting the browser just execute it all in one go without even needing to look for a file has huge benefits.
It’s also a lot more robust. Fetching external resources is much more fragile than people tend to imagine.
athanagor2|10 months ago
sebazzz|10 months ago
At our place we do abide by those rules, but we also use 3rd party components like Telerik/Kendo which require both unsafe-inline for scripting and styling. Sometimes you have no choice laxing your security policy.
pocketarc|10 months ago
I absolutely agree with you. I've been very very keen on CSP for a long time, it feels SO good to know that that vector for exploiting vulnerabilities is plugged.
One thing that's very noticeable: It seems to block/break -a lot- of web extensions. Basically every error I see in Sentry is of the form of "X.js blocked" or "random script eval blocked", stuff that's all extension-related.
midtake|10 months ago
Do you mean people should be banned from inlining Google Analytics or Meta Pixel or Index Now or whatever, which makes a bunch of XHRs to who knows where? Absolutely!
But nerfing your own page performance just to make everything CSP-compliant is a fool's errand.
myko|10 months ago
davidmurdoch|10 months ago
Here is the 9 year old bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1267027
And their extension store does not permit workarounds, even though they themselves have confirmed it's a bug.
evilpie|10 months ago
For example I helped uBlock Origin out in 2022 when they ran into this: https://github.com/uBlockOrigin/uBlock-issues/issues/235#iss...
Semaphor|10 months ago
gear54rus|10 months ago
pama|10 months ago
lol768|10 months ago
I appreciate they had to move for other reasons but I also really don't like the idea that the DevTools and browser chrome itself now has all of the same security issues/considerations as anything else "web" does. It was bad with Electron (XSS suddenly becoming an RCE) and makes me pretty nervous here too :(
emiliocobos|10 months ago
myfonj|10 months ago
That would keep "static form" helpers still functional, but disable (malicious) runtime templating.
yanis_t|10 months ago
I recently implemented a couple of tools to generate[1] and validate[2] a CSP. Would be glad if anybody tries it.
[1] https://www.csphero.com/csp-builder [2] https://www.csphero.com/csp-validator
CamouflagedKiwi|10 months ago
Obviously hard to say what those tradeoffs are worth, but I'd be a bit nervous about it. The work covered by this post is a good thing, of course!
b112|10 months ago
Why? Some sites implement then break this, sadly.
I have extremely locked down instances for banks and so on. On Linux I have an icon which lets me easily launch those extra profiles.
I also use user.js, which means I can just drop in changes, and write comments for each config line, and keep it version controlled too. Great for cloning to other devices too.
SebFender|10 months ago
sixaddyffe2481|10 months ago
foobar9898989|10 months ago