预告片标头中的 Content-Security-Policy 标头不起作用
Posted
技术标签:
【中文标题】预告片标头中的 Content-Security-Policy 标头不起作用【英文标题】:Content-Security-Policy Header in trailer header isn't working 【发布时间】:2021-12-20 04:20:51 【问题描述】:我设置了一个简单的 nodejs http-server 流式处理 html 请求。随着 html 的流式传输,它会将任何内联内容提取到单独的元素中并计算其哈希值。 在最后一步中,发送包含原始 csp + 新哈希的尾部标题。 (这是唯一的csp发送,在服务端合并!)
但是,浏览器(所有:Chrome、Firefox、Edge)不支持 csp! (根据canIuse,所有这些浏览器都支持预告片头。)
上面的伪代码(类似node-js):
const server = http.createServer((reqest, response) =>
response.setHeader('Transfer-Encoding', 'chunked');
response.setHeader('content-type', 'text/html');
response.setHeader('Trailer', 'content-security-policy');
const stream = getHTMLSAXStream();
stream.on('data', function(element)
// extract inlines and save, e.g. styles.push(element.style);
// then remove the attr: e.g. element.style = undefined;
// then on the stripped html: e.g. response.write(element.toHTML())
);
stream.on('end', function()
const stylefile= `$styles.join("\n")`;
const url = getUrlForString(stylefile); // make this file available on a temporary url
response.write(`<link rel="stylesheet" href="$url">`)
response.addTrailers( 'content-security-policy': mergeWithDefaultCSP("style-src: sha256-$sha256(stylefile)") );
response.end(); // send response
)
根据MDN docs on trailers,某些标头是不允许的,但是找不到不应该允许content-security-policy 的原因。 更具体地说,根据trailerheader 和csp spec:
发件人不得生成包含必要字段的预告片 对于消息帧(例如,传输编码和内容长度), 路由(例如,主机),请求修饰符(例如,控件和 [RFC7231] 第 5 节中的条件),身份验证(例如,参见 [RFC7235] 和 [RFC6265]),响应控制数据(例如,参见第 7.1 节 [RFC7231]),或确定如何处理有效载荷(例如, Content-Encoding、Content-Type、Content-Range 和 Trailer)。
CSP 不用于消息帧,不用于路由,不用作请求修饰符,不用于身份验证,也不用于处理负载(仅在处理负载后使用,又名html) - 简而言之,我看不出它不应该工作的原因!
有人知道吗?我错过了什么吗?
为了解决这个问题,目前我正在使用以下解决方法(我想摆脱):
不要使用哈希,按域列入白名单(例如,所有脚本都来自同一个域) 使用 nounces 而不是 hashes(虽然不能很好地与 cdns 配合使用)关于背景的更多信息,我为什么要这样做: 我有一个允许使用我经常使用的原始 html(包括内联样式和脚本标签)的 cms(否则我需要再次部署,等等)。另一方面,我想要一个良好的工作 CSP(例如,当用户生成的 cmets 使用 javascript 从 api 加载到页面上时(不在后端,这会破坏目的!),以防万一。因此我我想只允许我自己的内联样式和脚本标签,但不允许其他人。上面充分解决了这个问题。
【问题讨论】:
【参考方案1】:无论规范怎么说,这取决于浏览器是否支持,最后 I 标头浏览器对尾随标头的支持非常有限:Do any browsers support trailers sent in chunked encoding responses?
此外,我认为这对 CSP 没有意义,原因有两个:
HTML 通常是流式传输的(正如您所说的那样),并且浏览器将在 HTML 进入时呈现。然后回顾性地将 CSP 应用于已呈现的内容将毫无意义 - 损害已经造成。
多个 CSP 是相加的,而不是替代的。 IE。它是最重要的 CSP。因此,如果您有一个基本的 CSP,然后想要添加一个 AFAIK 不可能的随机数。
【讨论】:
以上是关于预告片标头中的 Content-Security-Policy 标头不起作用的主要内容,如果未能解决你的问题,请参考以下文章
杭州 Meetup 预告 | 分布式事务在 TiDB 中的实现,了解一下?
广告片要如何拍摄,这些方法你知道吗?流量雨广告片拍摄制作公司
直播预告:Apache SkyWalking 在 Service Mesh 中的可观察性应用