¿Cómo puedo migrar de filter-on-output a filter-on-input?

3

Recientemente me uní a una compañía con una aplicación PHP de más de un millón de líneas de código. El enfoque de seguridad de XSS parece ser filtrar la salida cada vez que el desarrollador lo piensa. No es sorprendente que no hayan captado todo, y tenemos algunas oportunidades XSS realmente increíbles.

En una vida pasada, he usado el enfoque defensores de Rasmus : filter all input para que sea seguro XSS, y no se preocupe por la visualización. Este enfoque funcionó bien: la mayoría de los datos funcionan perfectamente la mayor parte del tiempo, y el código que usa filter(UNSAFE_RAW) no está exactamente prohibido, pero seguramente recibe mayor atención en las revisiones de código.

El problema que tengo es: ¿cómo migras de un enfoque a otro? Parece que ahora tendré que codificar todo el contenido de la base de datos y jugar a whack-a-mole para eliminar todos los nuevos errores de doble codificación que descubriré. (Debería ser un pequeño más fácil ya que puedo grep para la existencia de htmlspecialchars() pero no puedo grep para su ausencia .: ))

Una respuesta realmente útil podría ser un blog sobre un proyecto exitoso o incluso una autopsia.

    
pregunta Jeremy Wadhams 18.09.2013 - 23:39
fuente

1 respuesta

5

El filtro en la salida es el método preferido de la defensa XSS. Una de las razones por las que este método de defensa XSS es popular es porque no depende de los datos de su base de datos que se ajusten a un conjunto de codificación arbitrario. Filtro en entrada significa que la vista de la aplicación debe confiar en la base de datos, ya que se supone que estos datos ya se han "filtrado". Si la base de datos está comprometida con la inyección SQL, un atacante podría introducir datos contaminados en la base de datos. Este es un exploit que escribí que usa la inyección SQL para obtener XSS persistente en una aplicación de filtro de entrada , XSS persistente no hubiera sido posible en un paradigma de filtro en salida.

Filter-on-output también es un enfoque más seguro para la defensa XSS, y te daré un ejemplo en PHP.

Digamos que tenemos una aplicación PHP que usa htmlspeicalchars($var, ENT_QUOTES); a ciegas, en todas las entradas. El caso clásico de un atacante que introduce <script>alert(1)</script> se evitaría en la mayoría de los casos (una operación de decodificación como base64decode() realizada después de htmlspeicalchars() resultaría en datos contaminados). Sin embargo, esta medida de seguridad general no impide que todos los XSS en la aplicación, lo más importante es que no impedirá que XSS en DOM eventos . Por ejemplo:

<img src="CoolPic.jpg" onclick="doSomethingCool('userInput&#000000039;);alert(document.cookie);//');" />

O aquí hay otro ejemplo, donde javascript:alert(1) es la carga útil:

<a href=javascript:alert(1)>go back</a>

No todos los datos se utilizan de la misma manera, por lo tanto, es imposible aplicar una medida de seguridad general. Las URL se ajustan a reglas XSS diferentes a las de los controladores de eventos, y ambas son muy diferentes del caso general de XSS.

Entonces, ¿cómo se migra de un filtro en salida a un filtro en entrada? NO . La mejor manera de prevenir XSS es usar un sistema tentador que tenga en cuenta XSS como Twig . XSS es un problema con la vista, por lo que necesita una vista que sea segura.

    
respondido por el rook 19.09.2013 - 01:07
fuente

Lea otras preguntas en las etiquetas