Primefaces CSP与faces.js兼容问题:如何安全共存?
问题背景
环境版本:faces 2.2 Faces JavaScript Library、Mojarra Faces 4.0.7
已在web.xml中开启Primefaces.CSP并为JS生成nonce值,但部分xhtml页面中faces.js违反CSP的unsafe-inline规则,报错信息:Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self'"
违规代码片段:if (!!script) { var scriptNode = document.createElement("script"); scriptNode.type = "text/javascript"; scriptNode.text = script; head.appendChild(scriptNode); // 此处违反规则 head.removeChild(scriptNode) }
可行解决方案
为动态脚本添加nonce属性
既然已配置nonce生成,需要让faces.js中动态创建的<script>标签带上与CSP头一致的nonce。可以修改faces.js的脚本创建逻辑:if (!!script) { var scriptNode = document.createElement("script"); scriptNode.type = "text/javascript"; // 从页面已有的Primefaces脚本中提取nonce值 var primeScript = document.querySelector('script[nonce]'); if (primeScript) { scriptNode.nonce = primeScript.nonce; } scriptNode.text = script; head.appendChild(scriptNode); head.removeChild(scriptNode) }若无法直接修改
faces.js,可通过自定义JS在页面加载时覆盖相关方法,或利用Mojarra扩展机制调整脚本生成逻辑。添加脚本哈希到CSP规则
计算违规inline脚本内容的SHA哈希(推荐SHA-256/SHA-384),将哈希值加入CSP的script-src指令。例如:script-src 'self' 'sha256-xxxxxx...';这种方式无需修改代码,但要注意脚本内容变更时需同步更新哈希值。
升级Mojarra版本
Mojarra 4.0.7可能存在CSP兼容缺陷,升级至最新4.x版本,官方大概率已修复faces.js动态脚本的CSP适配问题,使其自动支持nonce或哈希。调整Primefaces CSP配置
在web.xml中扩展Primefaces的CSP规则,确保script-src包含nonce或哈希:<context-param> <param-name>primefaces.CSP</param-name> <param-value>true</param-value> </context-param> <context-param> <param-name>primefaces.CSP_SCRIPT_SRC</param-name> <param-value>'self' 'nonce-${nonce}'</param-value> </context-param>同时确认Mojarra能正确传递并使用该nonce值生成动态脚本。
内容的提问来源于stack exchange,提问作者László Tóth

