Pdf.js: La microoptimización del estilo de la capa de texto resultó en requerir style-src 'inseguro-en línea' en la Política de seguridad del contenido

Creado en 13 feb. 2017  ·  11Comentarios  ·  Fuente: mozilla/pdf.js

https://github.com/mozilla/pdf.js/commit/cb5f9df0c8932fe0db9f783ede7893b7efcadcdb comenzó a generar cadenas de estilo automáticamente, lo cual está prohibido por una Política de seguridad de contenido estándar. Sería bueno tener una alternativa o quizás reconsiderar el enfoque.

Para reproducir, use style-src 'self' en CSP:

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

Comentario más útil

En caso de que alguien más se encuentre con esto y quiera una solución, este es mi parche actual que lo revierte a la forma anterior de hacerlo, de modo que se pueda evitar style-src: 'unsafe-inline' :

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

Definitivamente se puede optimizar un poco, pero como eso no importa para mi uso, mantengo el parche lo más mínimo posible para facilitar el mantenimiento. Creo que esperar que alguien que quiera solucionar este problema de seguridad se preocupe por optimizar el rendimiento es un poco al revés. La optimización del rendimiento debería haberse limitado a lo que se puede hacer sin romper la higiene de seguridad básica. Incluso puede ser más rápido abordar esto de una manera diferente como mencioné anteriormente. El mensaje de confirmación para la optimización menciona lo difícil que fue medir una diferencia, pero la regresión de seguridad se mide con bastante facilidad.

La razón por la que estoy usando pdf.js en primer lugar es la seguridad. Permite reutilizar el renderizado del navegador reforzado / aislado con todo el renderizado específico de PDF en un lenguaje seguro para la memoria (JavaScript). Como parte de hacer esto, estoy usando CSP para mitigar la inyección dinámica de código / estilo que podría aumentar masivamente la superficie de ataque para que sea como una página web, lo cual es muy contrario a los objetivos. Creo que muchas otras personas tienen un caso de uso similar para pdf.js para evitar peligrosas bibliotecas de representación de PDF nativas. Evitar los estilos unsafe-inline es parte de asegurarse de que un error no pueda resultar en la inyección accidental de estilos arbitrarios, lo que abre una gran cantidad de superficie de ataque del renderizador. Para un caso de uso en el que está incrustado en un sitio web real, es aún más importante, ya que se pueden hacer muchas cosas malas con CSS.

Considero esto al mismo nivel que esperar que las bibliotecas / binarios nativos tengan SSP, ASLR (PIE), _FORTIFY_SOURCE=2 , -fstack-clash-protection y otras mitigaciones de referencia. Es la higiene de seguridad básica frente a cosas más avanzadas como CFI basado en tipos, captura de desinfectantes de números enteros, ShadowCallStack, etc., donde espero que los proyectos más grandes estén pensando en ello y tal vez ya estén trabajando en ello, pero no es parte del mínimo indispensable. En mi opinión, una política de CSP básica con JavaScript / CSS estático califica como higiene de seguridad básica.

Todos 11 comentarios

... o quizás reconsiderar el enfoque.

El PR # 7632 era necesario para mejorar el rendimiento del modo enhanceTextSelection en particular, que es parte del problema # 7584, por lo que en mi opinión no creo que se deba considerar revertir esto.

Solo sugiero tomar otras rutas para optimizarlo. Por ejemplo, ¿por qué usar 4 atributos de relleno y luego aplicarlos con style lugar de fusionarlos?

También podría seguir usando el enfoque de matriz estática para establecer propiedades de estilo individuales en lugar de hacerlo todo a través de style . Las propiedades font-family y font-size podrían fusionarse como padding .

Solo sugiero tomar otras rutas para optimizarlo. Por ejemplo, ¿por qué usar 4 atributos de relleno y luego aplicarlos con estilo en lugar de fusionarlos?

En general, no hay garantía de que un textDiv necesite los cuatro valores de relleno actualizados con enhanceTextSelection , y el código actual proporcionó una forma sencilla de manejar ese caso (muy común).

También podría seguir utilizando el enfoque de matriz estática para establecer propiedades de estilo individuales en lugar de hacerlo todo a través del estilo.

La línea general de razonamiento detrás de actualizar todo a la vez usando style , fue tratar de evitar invalidar innecesariamente el DOM al crear / actualizar los textDiv s, ya que parecía ser uno de los principales contribuyentes a mal desempeño del modo enhanceTextSelection .

En general, no hay garantía de que un textDiv en particular necesite los cuatro valores de relleno actualizados conhanceTextSelection, y el código actual proporcionó una forma sencilla de manejar ese caso (muy común).

Eso no significa que padding no se pueda usar de manera eficiente. No necesita construir nuevas cadenas para las partes que no está actualizando y el resultado final será menor. Puede reemplazar un solo conjunto de atributos style con un solo conjunto style.padding y se puede reutilizar "0".

La línea general de razonamiento detrás de actualizar todo a la vez usando style, fue tratar de evitar invalidar innecesariamente el DOM al crear / actualizar los textDivs, ya que parecía ser uno de los principales contribuyentes al mal desempeño del modohanceTextSelection.

¿No está sucediendo en un fragmento, no en el DOM real?

Eso no significa que el acolchado no se pueda usar de manera eficiente.

@thestinger está de acuerdo, ayudará a abordar el problema si se dispusiera de puntos de referencia con algunos datos de rendimiento.

Realmente no puedo medir una diferencia entre diferentes enfoques aquí. Sin embargo, los diferentes enfoques pueden ser microbenchmarked fuera de contexto.

Creo que el conflicto con unsafe-inline se puede reducir sin una pérdida de rendimiento ajustando esto y luego la optimización se puede condicionar si mantenerla es importante.

Es fácil para mí revertir este compromiso, por lo que no es una prioridad para mí, pero intentaré encontrar a alguien que trabaje en ello. Sería genial tener pruebas para cosas de CSP para que no puedan fallar en el futuro (optimizaciones como esta aún podrían suceder si son importantes, solo tendrían que ser condicionales).

Es posible que exista una solución que permita la optimización tal como está mientras admite sitios web que utilizan CSP.

Hay tres formas de establecer el estilo en línea como una cadena:

  • element.setAttribute('style', someStyle) , que no funciona cuando hay un CSP que no permite inseguridad en línea
  • element.style = someStyle , que no es compatible con IE (probado en IE 11, no lo he probado en Edge, por lo que también podría estar roto allí)
  • element.style.cssText = someStyle , que se admite a partir de DOM nivel 2, por lo que incluso IE lo admite (verificado en IE 11)

Plunker para mostrar los tres métodos: https://plnkr.co/edit/T8xrUmR5eSuqDukSEVuw?p=preview

Estaría más que dispuesto a hacer una solicitud de extracción cambiando element.setAttribute('style', ...) a element.style.cssText = ... si está de acuerdo con esta solución.

En caso de que alguien más se encuentre con esto y quiera una solución, este es mi parche actual que lo revierte a la forma anterior de hacerlo, de modo que se pueda evitar style-src: 'unsafe-inline' :

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

Definitivamente se puede optimizar un poco, pero como eso no importa para mi uso, mantengo el parche lo más mínimo posible para facilitar el mantenimiento. Creo que esperar que alguien que quiera solucionar este problema de seguridad se preocupe por optimizar el rendimiento es un poco al revés. La optimización del rendimiento debería haberse limitado a lo que se puede hacer sin romper la higiene de seguridad básica. Incluso puede ser más rápido abordar esto de una manera diferente como mencioné anteriormente. El mensaje de confirmación para la optimización menciona lo difícil que fue medir una diferencia, pero la regresión de seguridad se mide con bastante facilidad.

La razón por la que estoy usando pdf.js en primer lugar es la seguridad. Permite reutilizar el renderizado del navegador reforzado / aislado con todo el renderizado específico de PDF en un lenguaje seguro para la memoria (JavaScript). Como parte de hacer esto, estoy usando CSP para mitigar la inyección dinámica de código / estilo que podría aumentar masivamente la superficie de ataque para que sea como una página web, lo cual es muy contrario a los objetivos. Creo que muchas otras personas tienen un caso de uso similar para pdf.js para evitar peligrosas bibliotecas de representación de PDF nativas. Evitar los estilos unsafe-inline es parte de asegurarse de que un error no pueda resultar en la inyección accidental de estilos arbitrarios, lo que abre una gran cantidad de superficie de ataque del renderizador. Para un caso de uso en el que está incrustado en un sitio web real, es aún más importante, ya que se pueden hacer muchas cosas malas con CSS.

Considero esto al mismo nivel que esperar que las bibliotecas / binarios nativos tengan SSP, ASLR (PIE), _FORTIFY_SOURCE=2 , -fstack-clash-protection y otras mitigaciones de referencia. Es la higiene de seguridad básica frente a cosas más avanzadas como CFI basado en tipos, captura de desinfectantes de números enteros, ShadowCallStack, etc., donde espero que los proyectos más grandes estén pensando en ello y tal vez ya estén trabajando en ello, pero no es parte del mínimo indispensable. En mi opinión, una política de CSP básica con JavaScript / CSS estático califica como higiene de seguridad básica.

Corregido por la solicitud de extracción anterior.

¿Fue útil esta página
0 / 5 - 0 calificaciones