https://github.com/mozilla/pdf.js/commit/cb5f9df0c8932fe0db9f783ede7893b7efcadcdbは、スタイル文字列の自動生成を開始しました。これは、標準のコンテンツセキュリティポリシーで禁止されています。 フォールバックを行うか、アプローチを再検討することをお勧めします。
再現するには、CSPでstyle-src 'self'
を使用します。
<meta http-equiv="Content-Security-Policy" content="style-src 'self'" />
...またはおそらくアプローチを再考します。
特にenhanceTextSelection
モードのパフォーマンスを向上させるためにPR#7632が必要でしたが、これは問題#7584の一部であるため、これを元に戻すことも検討すべきではないと思います。
私はそれを最適化するために他のルートを取ることを提案しているだけです。 たとえば、4つのパディング属性を使用してから、それらをマージする代わりにstyle
適用するのはなぜですか?
style
介してすべてを行う代わりに、静的配列アプローチを使用して個々のスタイルプロパティを設定することもできます。 font-family
プロパティとfont-size
プロパティは、 padding
ようにマージできます。
私はそれを最適化するために他のルートを取ることを提案しているだけです。 たとえば、4つのパディング属性を使用してから、それらをマージするのではなく、スタイルで適用するのはなぜですか?
一般に、特定のtextDiv
がenhanceTextSelection
で更新された4つのパディング値すべてを必要とするという保証はなく、現在のコードはその(非常に一般的な)ケースを処理する簡単な方法を提供しました。
すべてをスタイル経由で行うのではなく、静的配列アプローチを使用して個々のスタイルプロパティを設定することもできます。
style
を使用してすべてを一度に更新する背後にある一般的な理由は、 textDiv
作成/更新するときに、DOMを不必要に無効にしないようにすることでした。 enhanceTextSelection
モードのパフォーマンスが悪い。
一般に、特定のtextDivがenhanceTextSelectionで更新された4つのパディング値すべてを必要とするという保証はなく、現在のコードはその(非常に一般的な)ケースを処理する簡単な方法を提供しました。
これは、 padding
を効率的に使用できないという意味ではありません。 更新していない部分の新しい文字列を作成する必要はなく、最終結果は小さくなります。 単一のstyle
属性セットを単一のstyle.padding
セットに置き換えることができ、「0」を再利用できます。
スタイルを使用してすべてを一度に更新する背後にある一般的な理由は、textDivを作成/更新するときにDOMを不必要に無効にしないようにすることでした。これは、enhanceTextSelectionモードのパフォーマンス低下の主な原因の1つであると思われるためです。
実際のDOMではなく、フラグメントで発生しているのではありませんか?
これは、パディングを効率的に使用できないという意味ではありません。
@thestingerは同意します。いくつかのパフォーマンスデータを含むベンチマークが利用可能であれば、問題に対処するのに役立ちます。
ここでは、さまざまなアプローチの違いを実際に測定することはできません。 ただし、さまざまなアプローチをコンテキスト外でマイクロベンチマークすることができます。
unsafe-inline
との競合は、これを調整することでパフォーマンスを低下させることなく減らすことができ、それを維持することが重要な場合は、最適化を条件付きにすることができると思います。
このコミットを元に戻すのは簡単なので、優先度は高くありませんが、作業してくれる人を探します。 将来壊れないように、CSPのもののテストを行うのは素晴らしいことです(このような最適化は、重要な場合でも発生する可能性があり、条件付きである必要があります)。
CSPを使用してWebサイトをサポートしながら、そのまま最適化できるソリューションがあるかもしれません。
インラインスタイルを文字列として設定するには、次の3つの方法があります。
element.setAttribute('style', someStyle)
、これは、安全でないインラインを許可しないCSPがある場合は機能しませんelement.style = someStyle
、これはIEではサポートされていません(IE 11でテスト済みですが、Edgeでテストしていないため、そこでも破損する可能性があります)element.style.cssText = someStyle
、これはDOMレベル2の時点でサポートされているため、IEでもサポートされます(IE 11で確認済み)3つの方法を示すプランカー: 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を使用して、動的なコード/スタイルの挿入を軽減します。これにより、攻撃対象領域がWebページのように大幅に増加する可能性があり、これは目標に非常に反します。 他の多くの人々は、危険なネイティブPDFレンダリングライブラリを回避するためにpdf.jsの同様のユースケースを持っていると思います。 unsafe-inline
スタイルを回避することは、バグによって任意のスタイルが誤って挿入され、レンダラーの攻撃対象領域が大きくなることがないようにするための一部です。 実際のWebサイトに埋め込まれているユースケースでは、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を使用して、動的なコード/スタイルの挿入を軽減します。これにより、攻撃対象領域がWebページのように大幅に増加する可能性があり、これは目標に非常に反します。 他の多くの人々は、危険なネイティブPDFレンダリングライブラリを回避するためにpdf.jsの同様のユースケースを持っていると思います。
unsafe-inline
スタイルを回避することは、バグによって任意のスタイルが誤って挿入され、レンダラーの攻撃対象領域が大きくなることがないようにするための一部です。 実際のWebサイトに埋め込まれているユースケースでは、CSSを使用して多くの悪事を行うことができるため、さらに重要になります。これは、ネイティブバイナリ/ライブラリにSSP、ASLR(PIE)、
_FORTIFY_SOURCE=2
、-fstack-clash-protection、およびその他のベースライン緩和策があることを期待するのと同じレベルであると考えています。 これは基本的なセキュリティ衛生と、型ベースのCFI、トラッピング整数サニタイザー、ShadowCallStackなどのより高度なものであり、大規模なプロジェクトがそれについて考えており、おそらくすでに取り組んでいると予想していますが、最低限の部分ではありません。 私の意見では、静的JavaScript / CSSを使用した基本的なCSPポリシーは、基本的なセキュリティ衛生と見なされます。