Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.Sign up
CSP and HTML Modules #544
One developer pointed out that our use of inline scripts in HTML Modules could interact poorly with CSP’s
An HTML Module uses inline scripts for two primary purposes: to specify its exports, and to import other modules (script or HTML) that it depends on. The reason that inline scripts in particular are required is that a non-inline module script can be imported from multiple contexts, making its referrer document ambiguous, so it’s not clear how a non-inline script would interact with its referrer to specify exports of HTML content.
An HTML Module’s inline scripts are different from normal scripts in a few ways. Firstly, only
So, inline scripts in HTML Modules don’t have the same behavior as normal inline scripts. Another way to think about them is that they are declaratively specified script module imports of the HTML module. Additionally, it's impossible to dynamically inject a script into a module in such a way that it will execute; only scripts that were parsed with the original HTML Module are included in the module graph and executed.
Given the above, we believe that inline script elements included in HTML Modules should be allowed to run even without the presence ‘unsafe-inline’ in a script-src directive.
This decision clearly merits input from the experts. Does anyone in the WG have concerns with this? Are there any dangers here that we are missing?
Also worth noting is that we would propose to have the importing of HTML Modules governed under the script-src directive in the same way that it applies to importing of script modules.
One more question we're considering is whether or not an HTML module (which is a document) applies CSP directives specified in its headers when it is being processed as part of the module graph. We're thinking the answer is no -- that only the "root" document's CSP directives apply -- but we're not sure. On the one hand, if I want to consume a module hosted on a third-party server I shouldn't have to worry about whether the server’s lax CSP policies could compromise the security of my application. On the other hand, it seems unintuitive that a text/html response’s CSP is respected or not based on whether it’s getting pulled in as a module vs. loaded as a top-level document. Feedback on this is welcome as well.
We’ve also been considering the issue here regarding module imports in a nonced inline script, but this seems more applicable to ES6 modules in general with no special consideration needed for HTML Modules.
That's still the same basic problem though, no? If you find some kind of XSS (granted, it's more involved as there's multiple steps) an attacker gets to influence that.
I guess the main question if we see these as subresources that are similar to other subresources, or subresources prone to XSS due to their HTML-y nature.
I think HTML Modules isn't prone to XSS. Because it's not meant to dynamically generate HTML according to user input. Yes, there might be a DOM based XSS depending on inline scripts, but that's same as subresources like JS file.
There is some precedent for this in how HTML imports interacted with CSP. AFAIK they applied the loading document's
The main concern here is that HTML is frequently constructed unsafely, with user data interpolated without sufficient escaping; we can hope that HTML modules will be static as @shhnjk says, but there is no reason an application couldn't use user-controlled data when returning the contents of the module, leading to an XSS that wouldn't be subject to CSP, resulting in a security regression. OTOH we can also treat this more similarly to ES modules and assume that, once loaded, the module gets the ability to execute scripts -- I don't think that's necessarily a wrong way to look at this.
No concerns from me when it comes to inheriting the loading document's CSP. One thing to keep in mind in this model is that we should tell developers to always also set a CSP on the HTML module response. An attacker can navigate the victim to it directly so if there's a DOM XSS in a script in the HTML module, it would execute in the context of the hosting origin (which is difference between HTML modules and ES modules / JS subresources); developers would need to have CSP set on such responses even if the policy would normally get ignored.