Angular 18.2 Jenkins构建未注入ngCspMedia脚本致CSP报错
Angular 18.2 基于Nonce的严格CSP构建部署问题
环境背景
- Angular 18.2版本应用,采用Nonce实现严格Content-Security-Policy(CSP)
- 通过Jenkins构建部署,package.json中多个包使用
^18.2.0形式自动更新小版本 - 数周前应用运行正常,近期构建后出现CSP报错
报错信息
[our server].com/:67 "Refused to execute inline event handler because it violates the following Content Security Policy directive: "script-src 'self' 'nonce-PhZhJf6yjkLGyqjMeaTcmA==' 'unsafe-hashes'". Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce ('nonce-...') is required to enable inline execution."
当前排查情况
- 仅Jenkins构建部署后出现该报错
- 此前可正常运行的版本,通过Jenkins重新构建后同样报错
- Visual Studio中手动构建部署到服务器无报错,本地运行也正常
- 无论CSP脚本指令中是否配置
'unsafe-hashes',均触发报错
问题根源分析
Jenkins构建过程未检测到严格CSP配置,导致两个关键操作缺失:
- 未将
ngCspMedia脚本注入index.html - 未对
<link>元素做必要修改
临时验证:将Visual Studio构建生成的/dist/index.html中的ngCspMedia脚本复制到部署服务器的index.html中,应用可正常运行;但提前硬编码该脚本到index.html再构建无效。
应注入的ngCspMedia脚本
(() => { const CSP_MEDIA_ATTR = 'ngCspMedia'; const documentElement = document.documentElement; const listener = (e) => { const target = e.target; if (!target || target.tagName !== 'LINK' || !target.hasAttribute(CSP_MEDIA_ATTR)) { return; } target.media = target.getAttribute(CSP_MEDIA_ATTR); target.removeAttribute(CSP_MEDIA_ATTR); if (!document.head.querySelector(`link[${CSP_MEDIA_ATTR}]`)) { documentElement.removeEventListener('load', listener); } }; documentElement.addEventListener('load', listener, true); })();
已尝试的解决方案
- 确认Jenkins使用Angular 18.2版本CLI构建
- 在Visual Studio的PowerShell中执行
ng build,/dist/index.html成功注入该脚本 - 尝试在
index.html头部添加严格CSP元标签:
未解决问题<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'nonce-{nonce}'; style-src 'self' 'nonce-{nonce}';"> - 关闭样式优化后页面可加载(但仍未注入
ngCspMedia脚本),相关angular.json配置片段:"baseHref": "/[obfuscate]/", "optimization": { "scripts": true, "styles": false }, "outputHashing": "all", "sourceMap": false, "namedChunks": false, "aot": true, "extractLicenses": true, "vendorChunk": false, "buildOptimizer": true, "fileReplacements": [
内容的提问来源于stack exchange,提问作者JackDogStar
相关产品推荐
相关产品推荐

