Pdf.js: [email protected] 中不安全内联的 CSP 违规

创建于 2019-08-02  ·  24评论  ·  资料来源: mozilla/pdf.js

在此处附加(推荐)或链接到 PDF 文件:

配置:

  • Chrome 版本 76.0.3809.87(官方版本)(64 位)
  • Ubuntu 18.04.2 LTS(仿生海狸)
  • PDF.js 版本:pdfjs-dist v2.2.228
  • 是否为浏览器扩展:否

重现问题的步骤:
我们有防止unsafe-inline的内容安全策略。
v2.2.228 Function("r", "regeneratorRuntime = r")(runtime); 中的这一行违反了策略

附加信息:
类似问题 #10229

1-other

最有用的评论

我相信这个问题现在可以关闭,因为即将发布的版本将包含两种构建:

  • 现代构建(适用于最新的浏览器),使用 Babel 进行转译,也包含任何包含的 polyfill。
  • 一个 ES5 兼容的构建(例如可以与 IE11 一起使用),它使用 Babel 进行编译并包含所有必要的 polyfill。

所有24条评论

v2.2.228 Function("r", "regeneratorRuntime = r")(runtime); 中的这一行违反了策略

这实际上并不是源自 PDF.js 库本身任何地方的代码,而是来自在旧浏览器中支持async / await所需的 Babel polyfill。 因此,这是不幸的是没有完全清楚是什么(如果有的话)能约在这里完成。

是的,我认为这应该向上游报告。

@timvandermeij可以编写
@Snuffleupagus 关于whta 文件的任何提示?

仔细看了看。 没有机会 :-(

同样的问题在这里。

@Snuffleupagus可以分发 2 个单独的文件,一个用于旧浏览器,第二个用于常绿浏览器?

上游是否有任何问题需要跟踪? 目前面临同样的问题

您可以向https://github.com/facebook/regenerator报告问题

看起来 pdf.js 的作者在这里修复了这个问题

https://github.com/facebook/regenerator/pull/353

但是由于 babel 的问题,他们不得不回滚它

https://github.com/facebook/regenerator/pull/369

看起来我们在这里陷入了僵局。 我在这里看到三个解决方案:

  • 等到facebook/regenerator解决问题。
    这可能是最清楚的,但很多用户会坚持使用旧版本的 pdf.js
  • 降级facebook/regenerator (也许 babel 也必须降级)
  • 除了当前的 ES5 之外,还提供不需要facebook/regenerator的 pdf.js 的常青 (ES2016+) 版本。 (许多当前的 Web 应用程序不需要符合 ES5)。

无论如何,CSP 违规行为在此处有详细记录
https://github.com/facebook/regenerator/blob/6e9e8d7747c2ab49927bdd9dd6261753181faec1/packages/regenerator-runtime/runtime.js#L716 -L725

  // This module should not be running in strict mode, so the above
  // assignment should always work unless something is misconfigured. Just
  // in case runtime.js accidentally runs in strict mode, we can escape
  // strict mode using a global Function call. This could conceivably fail
  // if a Content Security Policy forbids using Function, but in that case
  // the proper solution is to fix the accidental strict mode problem. If
  // you've misconfigured your bundler to force strict mode and applied a
  // CSP to forbid Function, and you're not willing to fix either of those
  // problems, please detail your unique predicament in a GitHub issue.
  Function("r", "regeneratorRuntime = r")(runtime);

这意味着,如果您违反了 CSP,则不应在严格模式下运行它。 由于这是再生器运行时的已知行为,pdf.js 需要关闭严格模式。

@timvandermeij如果 pdf.js 有待办事项,您能否重新阅读评论?

我真的不明白 PDF.js 在这里可以做些什么不同的事情。 即使注释很明确,我们还是故意以严格模式运行 PDF.js 以防止错误并允许优化。 鉴于这之前没有发生过,我们甚至不直接使用facebook/regenerator (但仅作为另一个包的依赖项),我会说应该修补那些,除非我们可以/需要在我们这边做,但我不知道那会是什么......

@timvandermeij

谢谢你弄清楚。

pdf.js 的 babel 免费版本怎么样? 现代浏览器应该不需要再生器运行时 polyfill。

@jkroepke理想情况下,我们根本不会使用 Babel,但不幸的是,现在需要 PDF.js 在我们支持的所有浏览器中工作,因此我们现在无法考虑摆脱它。 当然,您可以自己构建 PDF.js 并禁用 Babel 转译。

我在 2.3.200 中遇到了同样的问题。 任何解决方法或修复? 谢谢。

@timvandermeij

最后,我看到 pdf.js 做错了,因为它使用了使用 regenerator-runtime/babel 时不支持的严格模式。 因此,这不再是上游问题,因为这些限制已被很好地记录在案。

我看到了 4 种解决此问题的替代方法:

  • 使用旧版本的 babel。 2.1.266 版本的 pdf.js 没有这个问题。 固定版本应该解决它。 这应该是最快的。
  • 不要使用严格模式,因为 babel 的依赖不支持它。
  • 使用 regenerator-runtime 关闭转译插件。 (https://caniuse.com/#feat=es6-generators)
  • 提供两个版本的pdfjs-dist。 一种用于旧浏览器(转换为 ES5),一种用于当前浏览器。 (转译为 ES6)

使用旧版本的 babel。 2.1.266 版本的 pdf.js 没有这个问题。 固定版本应该解决它。 这应该是最快的。

将依赖固定到旧版本从来都不是一个好主意,因为如果旧 Babel 版本中存在任何安全漏洞,它可能会导致问题。 此外,使用一个依赖项的旧版本可能会阻止、延迟和/或使其他依赖项的更新复杂化,从而导致其他问题。

[...](https://caniuse.com/#feat=es6-generators)

澄清一下async / await正在使用,这就是为什么这里存在这种特殊的依赖关系。

提供两个版本的pdfjs-dist。 一种用于旧浏览器(转换为 ES5),一种用于当前浏览器。 (转译为 ES6)

这似乎是上述建议中最现实的选择,但目前尚不清楚如何/何时发生(请注意 PR #11241 中的讨论/问题)。
但是,请注意,只有以下(一般)类型的构建才会被提供:

  • 构建仅与最新的ES-{version} 兼容,无论当时可能是什么,即构建的文件通过 Babel 运行并且包含 polyfill。
  • 与 ES5 兼容的构建,即构建的文件由 Babel 解析并包含 polyfill。

构建仅与最新的 ES-{version} 兼容

您是否尊重仅使用最新的 2 个主要浏览器版本支持的功能/技术?

新浏览器不支持的具有超级前沿语言建议功能的版本对我们没有帮助。

您是否尊重仅使用最新的 2 个主要浏览器版本支持的功能/技术?

这将需要生成三种不同类型的构建,这似乎不是一个好主意。 一方面,用户可能会对使用哪种构建更加困惑(因为我认为即使只有两种类型的构建,用户也不确定)。 此外,尝试提供多个构建也会给少数普通 PDF.js 贡献者带来更多压力,例如与支持和维护相关的压力。

基本上,就我而言,在这种情况下,理想的情况是图书馆用户:

  • 选择 ES 最新版本,并根据需要支持的平台/浏览器提供必要的 polyfill。
  • 选择 ES5 构建,并获得所有必要的 polyfills 和与“所有”现代浏览器兼容的代码。

新浏览器不支持的具有超级前沿语言建议功能的版本对我们没有帮助。

从历史上看,我认为我们从未在 Firefox Nightly 等功能可用时立即开始使用该功能,因此我无法预见这实际上会成为实践中的大问题。

你好,

我遇到了同样的问题,我使用的解决方案是直接加载regenerator-runtime认为我的 polyfill。

这样我就没有改变pdfjs-dist。 它使我无需重新编译 pdfjs 即可解决我的 CSP 问题:)

@makidelille你使用 angular 吗?

@makidelille你使用 angular 吗?

我们使用 angularjs(仍然)。

确切地说,我们在 pdf.js 之上构建了一个自定义查看器,该查看器通过 angularjs 指令使用

编辑:自定义查看器是用 typescript angularjs 构建的,这就是我们有 polyfills 的原因。

从这行代码中,我收到了另一个不安全的内联 CSS 错误:
https://github.com/mozilla/pdf.js/blob/master/web/ui_utils.js#L893

Refused to apply inline style because it violates the following Content Security Policy directive: "style-src ...". Either the 'unsafe-inline' keyword, a hash ('sha256-MW4Iy/yu3WipUpTMM/T6OjvUu9R6vUwutodlmYNo6qM='), or a nonce ('nonce-...') is required to enable inline execution.

你好,

我遇到了同样的问题,我使用的解决方案是直接加载regenerator-runtime认为我的 polyfill。

这样我就没有改变pdfjs-dist。 它使我无需重新编译 pdfjs 即可解决我的 CSP 问题:)

您(或其他任何人)是否知道此解决方案将如何转换为 angular 2+ ? 有没有可能解决这个问题?

我正在使用这个库并遇到相同的 CSP 问题(如果你愿意,你可以在那个项目问题列表中看到我的票),但是包/npm/依赖类型的东西的这类问题不是我掌握的所有内容好。

不幸的是,没有这个问题的旧版本 pdfjs(2.1.266,如上所述)似乎与这个 angular 2+ 包装库不兼容,而且它似乎没有使用那个版本的 pdfjs内部。

编辑:对于与我情况类似的任何人,还有另一个角度 pdfjs 包装器库对我有用,没有 CSP 问题。 见这里

我相信这个问题现在可以关闭,因为即将发布的版本将包含两种构建:

  • 现代构建(适用于最新的浏览器),使用 Babel 进行转译,也包含任何包含的 polyfill。
  • 一个 ES5 兼容的构建(例如可以与 IE11 一起使用),它使用 Babel 进行编译并包含所有必要的 polyfill。

听起来不错! 谢谢@Snuffleupagus ,每个人都致力于此:1st_place_medal:

此页面是否有帮助?
0 / 5 - 0 等级