-
Notifications
You must be signed in to change notification settings - Fork 25.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Inline <style> elements violates style-src Content Security Policy #6361
Comments
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
@IgorMinar Can this be fixed so we can write secure Angular apps ? |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
+1 As a workaround, we had to move all of our component level styles to a global style sheet. This meant creating See component styles and global styles for more information. Note: changing the view encapsulation did not seem to work (as some suggested). |
We did the same as @alexleen. |
Is this due to the shared_styles_host.ts file line 47? this._styleNodes.add(host.appendChild(styleEl)); This is the spot my CSP is identifying, and was wondering if this is the same issue? |
This comment has been minimized.
This comment has been minimized.
any update or workarounds for this issue ?
This doesn't seem to be work. Angular still adds the global styles as inline to the index.html file, not as a separate file. |
@redevill That |
@kgergooo Material has a couple of related, closed issues (angular/components#12139, angular/components#17783) but nothing open for CSP atm other then docs (angular/components#12795). If you can create a reproduction of the problem, please open a new issue at https://github.com/angular/components/issues/new/choose. |
Hijacking this issue as some discussion on We use Angular 9 for a true single-page application, meaning -- in addition to it being as good as a fully static website -- the server plays absolutely no part in templating whatsoever. With a "traditional" CSP configuration (which can be quite restrictive if we are specific about paths), we are still getting these violations from the
Each of these I suspect belong to webpack, flex-layout and/or ivy (could be material too but I didn't want to bother our front-end dev yet), and understand to be integral parts of Angular. This requires us to use The nonce-based "strict" mode is not a configuration that we can use, which is made clear by this FAQ. Using hashes is not a nice option either, since these hashes change on every build, even without changes in the code base! When we decided to use Angular some years ago, we decided to trust the community and company behind it, but we ended up being quite surprised that such basic and well-documented security practices are not yet covered, given that it has been more than 4-5 years since widespread adoption by browsers. Or, maybe Angular is ahead of the times... |
This comment has been minimized.
This comment has been minimized.
As I've expressed in this Angular Material issue, this is even affecting Angular Material and changes would be greatly appreciated. It would be great to have as a solution a possibility to add CSP nonces to the injected style tags. We have used 'unsafe-hashes' for some of the styles attributes but now, according to the government of Netherlands, which we have to comply to, these should be removed. If some other workaround is possible or a minor fix in a code would do, it would be great to get that information. |
Sorry for double post but I think that this post was overlooked. We would like to hear some reasoning from Google why they think the risk is low. Especially having in mind that we have to deal with Netherlands' government and their security concerns. |
@IgorMinar Do you have any official statement / source from the security team? The problem is, that many authorities at least in Europe nowadays require very strict CSP settings. "unsafe-inline" is simply not allowed and it is nearly impossible to discuss this topic with those kind of customers. As a result, Angular can not be used in these environments. |
Why on earth noone hit on the idea to provide their own
I mean @redevill even pointed to the right direction: #6361 (comment) Step 1Copy Contents of https://github.com/angular/angular/blob/main/packages/platform-browser/src/dom/shared_styles_host.ts Step 2Adjust the Service to fit your needs. Step 3Provide your own Implementation import { NgModule } from '@angular/core';
import {BrowserModule, ɵDomSharedStylesHost} from '@angular/platform-browser';
import { AppComponent } from './app.component';
import {CustomDomSharedStylesHostService} from "./custom-dom-shared-styles-host.service";
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
providers: [
{provide: ɵDomSharedStylesHost, useClass: CustomDomSharedStylesHostService} // PROVIDE OWN IMPLEMENTATION
],
bootstrap: [AppComponent]
})
export class AppModule { } Step 4Further improvements:
CodeCustomDomSharedStylesHostServiceSome Codeimport {Inject, Injectable} from "@angular/core";
import {DOCUMENT, ɵgetDOM as getDOM} from "@angular/common";
/**
* Contents copied from
* https://github.com/angular/angular/blob/main/packages/platform-browser/src/dom/shared_styles_host.ts
* Provides custom DomSharedStylesHostService with own logic
*/
const SOME_RANDOM_NONCE: string = "blabla";
@Injectable()
export class SharedStylesHost {
/** @internal */
protected _stylesSet = new Set<string>();
addStyles(styles: string[]): void {
const additions = new Set<string>();
styles.forEach(style => {
if (!this._stylesSet.has(style)) {
this._stylesSet.add(style);
additions.add(style);
}
});
this.onStylesAdded(additions);
}
onStylesAdded(additions: Set<string>): void {}
getAllStyles(): string[] {
return Array.from(this._stylesSet);
}
}
@Injectable()
export class CustomDomSharedStylesHostService extends SharedStylesHost {
private _hostNodes = new Map<Node, Node[]>();
constructor(@Inject(DOCUMENT) private _doc: any) {
super();
this._hostNodes.set(_doc.head, []);
}
private _addStylesToHost(styles: Set<string>, host: Node, styleNodes: Node[]): void {
styles.forEach((style: string) => {
const styleEl: HTMLStyleElement = this._doc.createElement('style');
styleEl.textContent = style;
// CUSTOM LOGIC
styleEl.setAttribute('nonce', SOME_RANDOM_NONCE)
console.log("Oh my gosh, 6 year old isse still open");
// CUSTOM LOGIC END
styleNodes.push(host.appendChild(styleEl));
});
}
addHost(hostNode: Node): void {
const styleNodes: Node[] = [];
this._addStylesToHost(this._stylesSet, hostNode, styleNodes);
this._hostNodes.set(hostNode, styleNodes);
}
removeHost(hostNode: Node): void {
const styleNodes = this._hostNodes.get(hostNode);
if (styleNodes) {
styleNodes.forEach(removeStyle);
}
this._hostNodes.delete(hostNode);
}
override onStylesAdded(additions: Set<string>): void {
this._hostNodes.forEach((styleNodes, hostNode) => {
this._addStylesToHost(additions, hostNode, styleNodes);
});
}
ngOnDestroy(): void {
this._hostNodes.forEach(styleNodes => styleNodes.forEach(removeStyle));
}
}
function removeStyle(styleNode: Node): void {
getDOM().remove(styleNode);
} cheers |
@flash-me What is wrong with this is that it's
|
Thx for the info! Was not aware of what cheers |
Apart from the solution being hacky, it doesn't fix the issues in angular sister projects like material and flex-layout. We are stuck with this at this point. |
I was able to implement the workaround from @ferdiesletering. But I encountered an error from the layout.mjs file. The error states:
As you see, there is a nonce in the CSP header, so why is layout.mjs still throwing this error on line 83: |
same issue for me |
Angular uses inline styles to insert the styles associated with a component. This violates the strict styles [Content Security Policy](https://web.dev/strict-csp/) which doesn't allow inline styles by default. One way to allow the styles to be applied is to set a `nonce` attribute on them, but because the code for inserting the stylesheets is deep inside the framework, users weren't able to provide it without accessing private APIs. These changes add a new `CSP_NONCE` injection token that will allow users to provide a nonce, if their app is using CSP. If the token isn't provided, the framework will look for an `ngCspNonce` attribute on the app's root node instead. The latter approach is provided as a convenience for apps that render the `index.html` through a server, e.g. `<app ngCspNonce="{% randomNonceAddedByTheServer %}"></app>`. These changes address adding the nonce to framework-generated styles. There will be follow-up PRs that add support for it in critical CSS tags in the CLI, and in Angular Material. Fixes angular#6361.
Angular uses inline styles to insert the styles associated with a component. This violates the strict styles [Content Security Policy](https://web.dev/strict-csp/) which doesn't allow inline styles by default. One way to allow the styles to be applied is to set a `nonce` attribute on them, but because the code for inserting the stylesheets is deep inside the framework, users weren't able to provide it without accessing private APIs. These changes add a new `CSP_NONCE` injection token that will allow users to provide a nonce, if their app is using CSP. If the token isn't provided, the framework will look for an `ngCspNonce` attribute on the app's root node instead. The latter approach is provided as a convenience for apps that render the `index.html` through a server, e.g. `<app ngCspNonce="{% randomNonceAddedByTheServer %}"></app>`. This PR addresses adding the nonce to framework-generated styles. There will be follow-up PRs that add support for it in critical CSS tags in the CLI, and in Angular Material. Fixes angular#6361.
Angular uses inline styles to insert the styles associated with a component. This violates the strict styles [Content Security Policy](https://web.dev/strict-csp/) which doesn't allow inline styles by default. One way to allow the styles to be applied is to set a `nonce` attribute on them, but because the code for inserting the stylesheets is deep inside the framework, users weren't able to provide it without accessing private APIs. These changes add a new `CSP_NONCE` injection token that will allow users to provide a nonce, if their app is using CSP. If the token isn't provided, the framework will look for an `ngCspNonce` attribute on the app's root node instead. The latter approach is provided as a convenience for apps that render the `index.html` through a server, e.g. `<app ngCspNonce="{% randomNonceAddedByTheServer %}"></app>`. This PR addresses adding the nonce to framework-generated styles. There will be follow-up PRs that add support for it in critical CSS tags in the CLI, and in Angular Material. Fixes angular#6361.
Angular uses inline styles to insert the styles associated with a component. This violates the strict styles [Content Security Policy](https://web.dev/strict-csp/) which doesn't allow inline styles by default. One way to allow the styles to be applied is to set a `nonce` attribute on them, but because the code for inserting the stylesheets is deep inside the framework, users weren't able to provide it without accessing private APIs. These changes add a new `CSP_NONCE` injection token that will allow users to provide a nonce, if their app is using CSP. If the token isn't provided, the framework will look for an `ngCspNonce` attribute on the app's root node instead. The latter approach is provided as a convenience for apps that render the `index.html` through a server, e.g. `<app ngCspNonce="{% randomNonceAddedByTheServer %}"></app>`. This PR addresses adding the nonce to framework-generated styles. There will be follow-up PRs that add support for it in critical CSS tags in the CLI, and in Angular Material. Fixes angular#6361.
Angular uses inline styles to insert the styles associated with a component. This violates the strict styles [Content Security Policy](https://web.dev/strict-csp/) which doesn't allow inline styles by default. One way to allow the styles to be applied is to set a `nonce` attribute on them, but because the code for inserting the stylesheets is deep inside the framework, users weren't able to provide it without accessing private APIs. These changes add a new `CSP_NONCE` injection token that will allow users to provide a nonce, if their app is using CSP. If the token isn't provided, the framework will look for an `ngCspNonce` attribute on the app's root node instead. The latter approach is provided as a convenience for apps that render the `index.html` through a server, e.g. `<app ngCspNonce="{% randomNonceAddedByTheServer %}"></app>`. This PR addresses adding the nonce to framework-generated styles. There will be follow-up PRs that add support for it in critical CSS tags in the CLI, and in Angular Material. Fixes angular#6361.
Angular uses inline styles to insert the styles associated with a component. This violates the strict styles [Content Security Policy](https://web.dev/strict-csp/) which doesn't allow inline styles by default. One way to allow the styles to be applied is to set a `nonce` attribute on them, but because the code for inserting the stylesheets is deep inside the framework, users weren't able to provide it without accessing private APIs. These changes add a new `CSP_NONCE` injection token that will allow users to provide a nonce, if their app is using CSP. If the token isn't provided, the framework will look for an `ngCspNonce` attribute on the app's root node instead. The latter approach is provided as a convenience for apps that render the `index.html` through a server, e.g. `<app ngCspNonce="{% randomNonceAddedByTheServer %}"></app>`. This PR addresses adding the nonce to framework-generated styles. There will be follow-up PRs that add support for it in critical CSS tags in the CLI, and in Angular Material. Fixes angular#6361.
Angular uses inline styles to insert the styles associated with a component. This violates the strict styles [Content Security Policy](https://web.dev/strict-csp/) which doesn't allow inline styles by default. One way to allow the styles to be applied is to set a `nonce` attribute on them, but because the code for inserting the stylesheets is deep inside the framework, users weren't able to provide it without accessing private APIs. These changes add a new `CSP_NONCE` injection token that will allow users to provide a nonce, if their app is using CSP. If the token isn't provided, the framework will look for an `ngCspNonce` attribute on the app's root node instead. The latter approach is provided as a convenience for apps that render the `index.html` through a server, e.g. `<app ngCspNonce="{% randomNonceAddedByTheServer %}"></app>`. This PR addresses adding the nonce to framework-generated styles. There will be follow-up PRs that add support for it in critical CSS tags in the CLI, and in Angular Material. Fixes angular#6361.
@flash-me solution makes only sense when you do what he says in the last point: load a different nounce everytime the application loads. otherwise it is not safe at all. |
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
See https://developer.mozilla.org/en-US/docs/Web/Security/CSP/CSP_policy_directives#style-src
The framework should support users that want to build their apps for CSP. In this case, the
style-src
directive would be in violation by Angular 2's use of inline<style>
elements for things like CSS encapsulation.I was curious if Angular 1 supported CSP, and it seems that Angular 1 indeed generates a stylesheet (
build/angular-csp.css
) that users can consume for CSP mode.cc @tbosch @matsko
The text was updated successfully, but these errors were encountered: