Pdf.js: Die Mikrooptimierung des Text-Layer-Stils führte dazu, dass style-src 'unsafe-inline' in der Inhaltssicherheitsrichtlinie verlangt wurde

Erstellt am 13. Feb. 2017  ·  11Kommentare  ·  Quelle: mozilla/pdf.js

https://github.com/mozilla/pdf.js/commit/cb5f9df0c8932fe0db9f783ede7893b7efcadcdb hat mit der automatischen Generierung von

Verwenden Sie zum Reproduzieren style-src 'self' in CSP:

    <meta http-equiv="Content-Security-Policy" content="style-src 'self'" />
2-performance 4-text-selection

Hilfreichster Kommentar

Falls jemand anderes darauf stößt und eine Lösung sucht, ist dies mein aktueller Patch, der dies auf die alte Vorgehensweise zurücksetzt, damit style-src: 'unsafe-inline' vermieden werden kann:

https://github.com/GrapheneOS/pdf.js/commit/021d2fddb03883054ef4399d1d3df87e0c6ab9ca

Es kann definitiv ein wenig optimiert werden, aber da das für meine Verwendung keine Rolle spielt, halte ich den Patch aus Gründen der Wartungsfreundlichkeit so minimal wie möglich. Ich denke, zu erwarten, dass jemand, der dieses Sicherheitsproblem beheben möchte, sich um die Optimierung der Leistung kümmert, ist ein bisschen rückständig. Die Leistungsoptimierung hätte auf das beschränkt werden sollen, was getan werden kann, ohne die grundlegende Sicherheitshygiene zu verletzen. Es kann sogar schneller sein, dies auf eine andere Weise als oben erwähnt anzugehen. Die Commit-Meldung für die Optimierung erwähnt, wie schwierig es war, überhaupt einen Unterschied zu messen, aber die Sicherheitsregression ist recht einfach zu messen.

Der Grund, warum ich pdf.js verwende, ist die Sicherheit. Es ermöglicht die Wiederverwendung des gehärteten / Sandbox-Browser-Rendering mit dem gesamten PDF-spezifischen Rendering in einer speichersicheren Sprache (JavaScript). Als Teil davon verwende ich CSP, um dynamische Code- / Style-Injection zu mildern, die die Angriffsfläche massiv auf eine Webseite vergrößern könnte, was den Zielen sehr zuwiderläuft. Ich denke, viele andere Leute haben einen ähnlichen Anwendungsfall für pdf.js, um gefährliche native PDF-Rendering-Bibliotheken zu vermeiden. Das Vermeiden von unsafe-inline Stilen ist Teil der Sicherstellung, dass ein Fehler nicht dazu führen kann, dass versehentlich beliebige Stile eingefügt werden, wodurch eine Menge Renderer-Angriffsfläche geöffnet wird. Für einen Anwendungsfall, bei dem es in eine tatsächliche Website eingebettet ist, ist es noch wichtiger, da mit CSS viele böse Dinge angestellt werden können.

Ich betrachte dies auf der gleichen Ebene wie die Erwartung, dass native Binärdateien / Bibliotheken über SSP, ASLR (PIE), _FORTIFY_SOURCE=2 , -fstack-clash-protection und andere grundlegende Abschwächungen verfügen. Es ist grundlegende Sicherheitshygiene im Vergleich zu fortgeschritteneren Dingen wie typbasiertem CFI, Abfangen von Integer-Desinfektionsmitteln, ShadowCallStack usw., wo ich erwarte, dass größere Projekte darüber nachdenken und vielleicht bereits daran arbeiten, aber es ist nicht Teil des Nötigsten. Eine grundlegende CSP-Policy mit statischem JavaScript / CSS gilt meiner Meinung nach als grundlegende Sicherheitshygiene.

Alle 11 Kommentare

... oder vielleicht den Ansatz überdenken.

PR #7632 war notwendig, um insbesondere die Leistung des enhanceTextSelection Modus, der Teil von Issue #7584 ist, zu verbessern, daher denke ich, dass eine Zurücksetzung nicht in Betracht gezogen werden sollte.

Ich schlage nur vor, andere Wege zur Optimierung zu nehmen. Warum zum Beispiel 4 Füllattribute verwenden und sie dann mit style anwenden, anstatt sie zusammenzuführen?

Könnte auch immer noch den statischen Array-Ansatz zum Festlegen einzelner Stileigenschaften verwenden, anstatt alles über style tun. Die Eigenschaften font-family und font-size könnten wie padding .

Ich schlage nur vor, andere Wege zur Optimierung zu nehmen. Warum zum Beispiel 4 Padding-Attribute verwenden und sie dann mit Stil anwenden, anstatt sie zusammenzuführen?

Im Allgemeinen gibt es keine Garantie dafür, dass ein bestimmtes textDiv alle vier Padding-Werte mit enhanceTextSelection aktualisiert benötigt, und der aktuelle Code bietet eine einfache Möglichkeit, diesen (sehr häufigen) Fall zu handhaben.

Könnte auch immer noch den statischen Array-Ansatz zum Festlegen einzelner Stileigenschaften verwenden, anstatt alles über den Stil zu tun.

Die allgemeine Überlegung, alles auf einmal mit style aktualisieren, bestand darin, zu vermeiden, dass das DOM unnötig ungültig gemacht wird, wenn die textDiv s erstellt/aktualisiert werden, da dies einer der Hauptfaktoren zu sein schien schlechte Leistung des enhanceTextSelection Modus.

Im Allgemeinen gibt es keine Garantie dafür, dass ein bestimmtes textDiv alle vier Padding-Werte benötigt, die mit EnhanceTextSelection aktualisiert wurden, und der aktuelle Code bietet eine einfache Möglichkeit, diesen (sehr häufigen) Fall zu handhaben.

Das bedeutet nicht, dass padding nicht effizient genutzt werden kann. Es müssen keine neuen Strings für die Teile erstellt werden, die es nicht aktualisiert, und das Endergebnis wird kleiner. Es kann einen einzelnen style Attributsatz durch einen einzelnen style.padding Satz ersetzen und „0“ kann wiederverwendet werden.

Die allgemeine Überlegung, alles auf einmal mithilfe von style zu aktualisieren, bestand darin, zu vermeiden, dass das DOM beim Erstellen/Aktualisieren der textDivs unnötig ungültig gemacht wird, da dies einer der Hauptgründe für die schlechte Leistung des EnhanceTextSelection-Modus zu sein schien.

Geschieht es nicht in einem Fragment, nicht im eigentlichen DOM?

Das bedeutet nicht, dass Polsterung nicht effizient verwendet werden kann.

@thestinger stimmt zu, es wird helfen, das Problem zu lösen, wenn Benchmarks mit einigen Leistungsdaten verfügbar waren.

Ich kann hier nicht wirklich einen Unterschied zwischen verschiedenen Ansätzen messen. Die verschiedenen Ansätze können jedoch aus dem Kontext gerissen werden.

Ich denke, der Konflikt mit unsafe-inline kann ohne Leistungsverlust reduziert werden, indem dies optimiert wird und dann die Optimierung bedingt gemacht werden kann, wenn es wichtig ist, sie beizubehalten.

Es ist einfach für mich, dieses Commit einfach rückgängig zu machen, daher hat es für mich keine hohe Priorität, aber ich werde versuchen, jemanden zu finden, der daran arbeitet. Es wäre toll, Tests für CSP-Zeug zu haben, damit es in Zukunft nicht kaputt gehen kann (Optimierungen wie diese könnten immer noch passieren, wenn sie wichtig sind, sie müssten nur bedingt sein).

Möglicherweise gibt es eine Lösung, die die Optimierung ermöglicht, während Websites mit CSP unterstützt werden.

Es gibt drei Möglichkeiten, den Inline-Stil als String festzulegen:

  • element.setAttribute('style', someStyle) , was nicht funktioniert, wenn es einen CSP gibt, der kein unsicheres Inline zulässt
  • element.style = someStyle , die im IE nicht unterstützt wird (getestet auf IE 11, ich habe dies nicht auf Edge getestet, daher könnte es auch dort defekt sein)
  • element.style.cssText = someStyle , die ab DOM Level 2 unterstützt wird, also auch IE unterstützt (verifiziert auf IE 11)

Plunker zum Anzeigen der drei Methoden: https://plnkr.co/edit/T8xrUmR5eSuqDukSEVuw?p=preview

Ich wäre mehr als bereit, eine Pull-Anfrage zu stellen, die element.setAttribute('style', ...) in element.style.cssText = ... ändert, wenn Sie dieser Lösung zustimmen.

Es scheint ein Browserfehler zu sein, wenn element.style.cssText = someStyle ohne unsafe-eval funktioniert:

Falls jemand anderes darauf stößt und eine Lösung sucht, ist dies mein aktueller Patch, der dies auf die alte Vorgehensweise zurücksetzt, damit style-src: 'unsafe-inline' vermieden werden kann:

https://github.com/GrapheneOS/pdf.js/commit/021d2fddb03883054ef4399d1d3df87e0c6ab9ca

Es kann definitiv ein wenig optimiert werden, aber da das für meine Verwendung keine Rolle spielt, halte ich den Patch aus Gründen der Wartungsfreundlichkeit so minimal wie möglich. Ich denke, zu erwarten, dass jemand, der dieses Sicherheitsproblem beheben möchte, sich um die Optimierung der Leistung kümmert, ist ein bisschen rückständig. Die Leistungsoptimierung hätte auf das beschränkt werden sollen, was getan werden kann, ohne die grundlegende Sicherheitshygiene zu verletzen. Es kann sogar schneller sein, dies auf eine andere Weise als oben erwähnt anzugehen. Die Commit-Meldung für die Optimierung erwähnt, wie schwierig es war, überhaupt einen Unterschied zu messen, aber die Sicherheitsregression ist recht einfach zu messen.

Der Grund, warum ich pdf.js verwende, ist die Sicherheit. Es ermöglicht die Wiederverwendung des gehärteten / Sandbox-Browser-Rendering mit dem gesamten PDF-spezifischen Rendering in einer speichersicheren Sprache (JavaScript). Als Teil davon verwende ich CSP, um dynamische Code- / Style-Injection zu mildern, die die Angriffsfläche massiv auf eine Webseite vergrößern könnte, was den Zielen sehr zuwiderläuft. Ich denke, viele andere Leute haben einen ähnlichen Anwendungsfall für pdf.js, um gefährliche native PDF-Rendering-Bibliotheken zu vermeiden. Das Vermeiden von unsafe-inline Stilen ist Teil der Sicherstellung, dass ein Fehler nicht dazu führen kann, dass versehentlich beliebige Stile eingefügt werden, wodurch eine Menge Renderer-Angriffsfläche geöffnet wird. Für einen Anwendungsfall, bei dem es in eine tatsächliche Website eingebettet ist, ist es noch wichtiger, da mit CSS viele böse Dinge angestellt werden können.

Ich betrachte dies auf der gleichen Ebene wie die Erwartung, dass native Binärdateien / Bibliotheken über SSP, ASLR (PIE), _FORTIFY_SOURCE=2 , -fstack-clash-protection und andere grundlegende Abschwächungen verfügen. Es ist grundlegende Sicherheitshygiene im Vergleich zu fortgeschritteneren Dingen wie typbasiertem CFI, Abfangen von Integer-Desinfektionsmitteln, ShadowCallStack usw., wo ich erwarte, dass größere Projekte darüber nachdenken und vielleicht bereits daran arbeiten, aber es ist nicht Teil des Nötigsten. Eine grundlegende CSP-Policy mit statischem JavaScript / CSS gilt meiner Meinung nach als grundlegende Sicherheitshygiene.

Behoben durch den Pull-Request oben.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen