https://github.com/mozilla/pdf.js/commit/cb5f9df0c8932fe0db9f783ede7893b7efcadcdb开始自动生成样式字符串,这是标准内容安全策略所禁止的。 最好有后备或重新考虑该方法。
要重现,请在 CSP 中使用style-src 'self'
:
<meta http-equiv="Content-Security-Policy" content="style-src 'self'" />
...或者也许重新考虑这种方法。
PR #7632 是必要的,特别是为了提高enhanceTextSelection
模式的性能,这是问题 #7584 的一部分,所以在我看来,我认为甚至不应该考虑恢复它。
我只是建议采取其他途径来优化它。 例如,为什么使用 4 个填充属性,然后将它们与style
而不是合并它们?
也可以仍然使用静态数组方法来设置单个样式属性,而不是通过style
。 font-family
和font-size
属性可以像padding
一样合并。
我只是建议采取其他途径来优化它。 例如,为什么使用 4 个填充属性,然后将它们与样式一起应用而不是合并它们?
通常,不能保证特定的textDiv
需要使用enhanceTextSelection
更新所有四个填充值,并且当前代码提供了一种处理这种(非常常见)情况的简单方法。
也可以仍然使用静态数组方法来设置单个样式属性,而不是通过样式来完成所有操作。
使用style
一次更新所有内容背后的一般推理是在创建/更新textDiv
时尝试避免不必要地使 DOM 无效,因为这似乎是enhanceTextSelection
模式的性能不佳。
通常,不能保证特定的 textDiv 需要使用 EnhanceTextSelection 更新所有四个填充值,并且当前代码提供了一种简单的方法来处理这种(非常常见的)情况。
这并不意味着padding
不能有效使用。 它不需要为它没有更新的部分构建新的字符串,最终结果会更小。 它可以代替单个style
具有属性组中的单个style.padding
设置和“0”可以重复使用。
使用样式一次更新所有内容背后的一般推理是在创建/更新 textDiv 时尝试避免不必要地使 DOM 无效,因为这似乎是 EnhanceTextSelection 模式性能不佳的主要因素之一。
它不是发生在片段中,而不是实际的 DOM 中吗?
这并不意味着不能有效地使用填充。
@thestinger同意,如果有一些性能数据的基准可用,它将有助于解决这个问题。
我真的无法衡量这里不同方法之间的差异。 但是,可以脱离上下文对不同的方法进行微基准测试。
我认为通过调整它可以减少与unsafe-inline
的冲突而不会降低性能,然后如果保持它很重要,优化可以有条件地进行。
我很容易恢复这个提交,所以这对我来说不是一个高优先级,但我会尝试找人来处理它。 对 CSP 的东西进行测试会很棒,这样它就不会在未来中断(如果重要的话,这样的优化仍然可能发生,它们只需要有条件)。
可能有一种解决方案可以在支持使用 CSP 的网站时按原样进行优化。
可以通过三种方式将内联样式设置为字符串:
element.setAttribute('style', someStyle)
,当存在不允许不安全内联的 CSP 时不起作用element.style = someStyle
,IE 不支持(在 IE 11 上测试过,我没有在 Edge 上测试过,所以它也可能在那里坏了)element.style.cssText = someStyle
,从 DOM level 2 开始支持,所以即使 IE 也支持它(在 IE 11 上验证)Plunker 展示三种方法: https ://plnkr.co/edit/T8xrUmR5eSuqDukSEVuw?p=preview
如果您同意此解决方案,我非常愿意提出将element.setAttribute('style', ...)
更改element.style.cssText = ...
的拉取请求。
如果element.style.cssText = someStyle
在没有unsafe-eval
情况下工作,这似乎是一个浏览器错误:
万一其他人遇到这个问题并想要一个解决方案,这是我当前的补丁,将其回滚到旧的方式,因此可以避免style-src: 'unsafe-inline'
:
https://github.com/GrapheneOS/pdf.js/commit/021d2fddb03883054ef4399d1d3df87e0c6ab9ca
它肯定可以稍微优化一下,但由于这对我的使用无关紧要,我将补丁保持在尽可能小以便于维护。 我认为期望有人想要解决这个安全问题来关心优化性能有点倒退。 性能优化应该被限制在不破坏基本安全卫生的情况下可以完成的事情。 正如我上面提到的那样,以不同的方式解决这个问题甚至可能更快。 优化的提交消息提到了衡量差异是多么困难,但安全回归很容易衡量。
我首先使用 pdf.js 的原因是安全性。 它允许在内存安全语言 (JavaScript) 中重用强化/沙盒浏览器渲染以及所有特定于 PDF 的渲染。 作为这样做的一部分,我使用 CSP 来减轻动态代码/样式注入,这可能会大量增加攻击面,使其类似于网页,这与目标非常背道而驰。 我认为许多其他人对 pdf.js 也有类似的用例,以避免使用危险的原生 PDF 渲染库。 避免unsafe-inline
样式是确保错误不会导致意外注入任意样式的一部分,从而打开许多渲染器攻击面。 对于嵌入在实际网站中的用例,它更重要,因为使用 CSS 可以完成许多邪恶的事情。
我认为这与期望本机二进制文件/库具有 SSP、ASLR (PIE)、 _FORTIFY_SOURCE=2
、-fstack-clash-protection 和其他基线缓解措施处于同一水平。 这是基本的安全卫生与更高级的东西,如基于类型的 CFI、捕获整数清理器、ShadowCallStack 等。我确实希望更大的项目正在考虑它,也许已经在研究它,但它不是最低限度的一部分。 在我看来,具有静态 JavaScript / CSS 的基本 CSP 策略符合基本安全卫生条件。
由上面的拉取请求修复。
最有用的评论
万一其他人遇到这个问题并想要一个解决方案,这是我当前的补丁,将其回滚到旧的方式,因此可以避免
style-src: 'unsafe-inline'
:https://github.com/GrapheneOS/pdf.js/commit/021d2fddb03883054ef4399d1d3df87e0c6ab9ca
它肯定可以稍微优化一下,但由于这对我的使用无关紧要,我将补丁保持在尽可能小以便于维护。 我认为期望有人想要解决这个安全问题来关心优化性能有点倒退。 性能优化应该被限制在不破坏基本安全卫生的情况下可以完成的事情。 正如我上面提到的那样,以不同的方式解决这个问题甚至可能更快。 优化的提交消息提到了衡量差异是多么困难,但安全回归很容易衡量。
我首先使用 pdf.js 的原因是安全性。 它允许在内存安全语言 (JavaScript) 中重用强化/沙盒浏览器渲染以及所有特定于 PDF 的渲染。 作为这样做的一部分,我使用 CSP 来减轻动态代码/样式注入,这可能会大量增加攻击面,使其类似于网页,这与目标非常背道而驰。 我认为许多其他人对 pdf.js 也有类似的用例,以避免使用危险的原生 PDF 渲染库。 避免
unsafe-inline
样式是确保错误不会导致意外注入任意样式的一部分,从而打开许多渲染器攻击面。 对于嵌入在实际网站中的用例,它更重要,因为使用 CSS 可以完成许多邪恶的事情。我认为这与期望本机二进制文件/库具有 SSP、ASLR (PIE)、
_FORTIFY_SOURCE=2
、-fstack-clash-protection 和其他基线缓解措施处于同一水平。 这是基本的安全卫生与更高级的东西,如基于类型的 CFI、捕获整数清理器、ShadowCallStack 等。我确实希望更大的项目正在考虑它,也许已经在研究它,但它不是最低限度的一部分。 在我看来,具有静态 JavaScript / CSS 的基本 CSP 策略符合基本安全卫生条件。