为什么 CSP script-src unsafe-inline 会在我的 Angular Web 应用程序上引发样式问题?
问题:
当我尝试删除 script-src
CSP 的 unsafe-inline
源时,我的 Angular Web 应用程序不再工作。
这个问题的根本原因是什么?
在 Angular@12+ 中使用 SCSS 时,Angular 在 index.html
上添加属性 onload
这会导致违反 CSP unsafe-inline
script-src
标头的源代码。
如何解决此问题并消除我的 Angular Web 应用程序上的此“安全漏洞”?
The issue:
When I try to remove unsafe-inline
source for script-src
CSP my Angular webapp does not work anymore.
What is the root cause of this issue ?
When using SCSS in Angular@12+, Angular add a property onload
on the index.html
<link rel="stylesheet" href="styles.672c1ac3d6da8cc311a2.css" media="print" onload="this.media='all'">
This results in a violation of the CSP unsafe-inline
source for script-src
header.
How to fix this issue and remove this "security breach" on my Angular web app ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
解决方案:
将
"inlineCritical": false
添加到angular.json
解决了该问题,因为它禁用了 Critical CSS 内联。为什么 Angular 会这么做?
当浏览器渲染页面时,必须等待CSS资源下载并解析。它可能会给人一种应用程序加载缓慢的(错误)印象,并影响首次内容绘制 (FCP) 时间。
避免这种情况的常用技术是将 CSS 直接内联到 HTML 中,以避免额外的请求(这是 Lighthouse 推荐的方法)。但您不想内联所有 CSS,否则下载 HTML 的时间会增加。您只想内联关键的 CSS 资源,这些资源会阻止渲染,并且您的用户将看到这些资源(您可以推迟 CSS 的其余部分)。
Angular CLI 在 v11.1 中引入了一个新选项来帮助我们解决这个问题:
inlineCSS
然后,CLI 将在后台使用
critters
提取应用程序的关键 CSS,并将它们直接内联到 HTML 中。使用上述配置运行 ng build --prod 会生成一个
index.html
文件,其中包含包含提取的关键 CSS 的样式元素和通常的styles.xxxxx。 css
使用以下方式异步加载:有关 unsafe-inline CSP 关键字的更多信息:https://content-security-policy.com/unsafe-inline/
The solution:
Adding
"inlineCritical": false
to theangular.json
solved the issue because it disable Critical CSS inlining.Why Angular does that?
When the browser renders a page, it has to wait for the CSS resources to be downloaded and parsed. It can give the (false) impression that the loading of your application is slow, and impacts the First Contentful Paint (FCP) time.
A common technique to avoid that is to inline the CSS directly in the HTML, to avoid an extra request (this is what Lighthouse recommends). But you don’t want to inline all your CSS, otherwise the time to download the HTML increases. You just want to inline critical CSS resources, the ones that blocks the rendering, and that your user will see (you can defer the rest of CSS).
The Angular CLI introduces a new option in v11.1 to help us with this:
inlineCSS
The CLI will then use
critters
under the hood to extract the critical CSS of your application, and inline them directly in the HTML.Running
ng build --prod
with the above configuration produces anindex.html
file with a style element containing the critical CSS extracted, and the usualstyles.xxxxx.css
is loaded asynchronously using:<link rel="stylesheet" href="styles.3d6bb69e3d075769b349.css" media="print" onload="this.media='all'">
For more informations about the unsafe-inline CSP keyword: https://content-security-policy.com/unsafe-inline/
现在,在 Angular 16 上,我们为这个期待已久的 CSP 功能提供了解决方案。
https://angular.io/guide/security#content-security-policy
Now on Angular 16 we have a solution for this long waited CSP feature.
https://angular.io/guide/security#content-security-policy
如果您使用 Angular Universal (SSR),则还必须在 server.ts 文件中禁用 inlineCriticalCss
找到
并添加
inlineCriticalCss: false
来源:https://github.com/angular/angular/issues/42098#issuecomment-841629552
If you're using Angular Universal (SSR), you must disable inlineCriticalCss in your server.ts file as well
Locate
And add
inlineCriticalCss: false
Source: https://github.com/angular/angular/issues/42098#issuecomment-841629552