Problemas al reproducir Ogg bajo Apache con ModSecurity desde Chrome y Chromium

HTML 5 y sus nuevos tags de <audio> y <video> terminaron desencadenando anoche, una batalla campal con mis neuronas.

A raíz de querer incorporar audio OGG en una de mis Webs, descubrí que si el audio estaba alojado en mi servidor, no se reproducía. En cambio, si modificaba la ruta del archivo de audio colocando una URI externa, el audio se reproducía sin problemas.

De allí en más, comencé a investigar si era necesario que el servidor tuviese algún requisito/configuración/cuidado/whatever para permitir la reproducción de audio. Hasta incluso, pedí ayuda por Twitter con la esperanza de que a alguien se le prendiese la lamparita y muchísimas personas colaboraron. Sin embargo, cuando hallé la respuesta final, me di cuenta que era mucho más compleja de lo que me esperaba.

El problema

  • Intentando acceder a la URL del archivo de audio, éste era loclizado y sin embargo no se podía acceder a él.
  • Con wget el archivo bajaba sin inconvenientes;
  • Con los navegadores Firefox, Chrome y Chromium (desde Ubuntu GNU/Linux) podía reproducir audio en el mismo formato sin inconvenientes, siempre y cuando estos archivos NO se encontrasen en mi servidor.

Contexto

Se trataba de un servidor Ubuntu 12.04, con Apache 2.2 y… ModSecurity instalado con el paquete de reglas de OWASP. Mi mayor sospecha estaba sobre estas últimas. Ya habíamos hablado la noche anterior con Dabo, sobre los falsos positivos de ModSecurity.

El camino hacia la solución

A través de Twitter, @mjimeneznet me explicaba que con solo los tags debería funcionar y que el server no necesitaba nada más. Lo mismo sobre los tags, mencionaba todo el mundo! Pero esto iba más allá de HTML 5. Había algo en el servidor, eso era seguro.

Y así fue que a @elrevo, @daviddfr, @hernanJ y @f_rojas se les ocurrió que podría ser necesario indicar los tipos MIME en Apache, ya sea a través de Virtual Host, en apache2.conf directamente o en .htaccess.

Tras agregar al VirtualHost un AddType con el formato ogg, probé y solo en Firefox, parecía haberse resuelto el problema. Sin embargo, en Chrome y Chromium aún seguía el fallo.

En eso apareció @MatiasKatz con quien desde Google Talk, estuvimos haciendo varias pruebas. Hasta que se me ocurrió mirar los logs de error de Apache. Hice un tail -f a los logs, y allí estaban «esperándome» esos «malditos»:

[Sat Dec 07 23:15:03 2013] [error] [client XXX.XXX.XXX.XXX]
<strong>ModSecurity: Access denied with code 403</strong> 
(phase 2). String match "bytes=0-" at REQUEST_HEADERS:Range. 
[<strong>file "/etc/modsecurity/base_rules/modsecurity_crs_20_protocol_violations.conf</strong>"]
[<strong>line "248"</strong>] [id "958291"] [rev "2.2.5"] 
[msg "Range: field exists and begins with 0."] [data "bytes=0-"]
[<strong>severity "NOTICE"</strong>] [tag "RULE_MATURITY/5"] 
[tag "RULE_ACCURACY/7"] 
[tag "https://www.owasp.org/index.php/ModSecurity_CRS_RuleID-958291"]
[tag "PROTOCOL_VIOLATION/INVALID_HREQ"]
[tag "http://www.bad-behavior.ioerror.us/documentation/how-it-works/"] 
[hostname "www.originalhacker.org"] [<strong>uri "/Fenster.ogg"</strong>] 
[unique_id "UqOr98bHXb0AAHj4CSkAAAAF"]

Este error se replicaba decenas de veces. Resaltado en negritas vemos:

  1. ModSecurity negaba el acceso con un error 403;
  2. La causa era el archivo de reglas crs_20 sobre violaciones de protocolo;
  3. La regla específica era la indicada en la línea 248 (vale aclarar que muchas veces, se edita la regla en cuestión y es otra la que prohíbe el acceso así que esto era para ser tomado con pinzas)
  4. La severidad del supuesto ataque evitado, era a penas un aviso (notice)
  5. Finalmente, la URI, era la de mi famoso archivo de audio Fenster.ogg

La parte más desagradable era que ninguna de las URL logueadas, era accesible, así que en principio, no tenía explicación ni justificación para esa regla.

Lo primero que hice para verificar si era o no ModSecurity quien me estaba jodiendo, fue mover el archivo a un directorio de pruebas a fin de eliminarlo de su origen pero mantenerlo en copia de resguardo. Reinicié Apache y el problema desapareció. Finalmente, solo comenté la regla en cuestión y volví a reiniciar Apache.

La solución

En el archivo de reglas modsecurity_crs_20_protocol_violations.conf comentar la regla de línea 248:

#SecRule REQUEST_HEADERS:Range "@beginsWith bytes=0-" "phase:2,
rev:'2.2.5',t:none,block,msg:'Range: field exists and begins with 0.',
logdata:'%{matched_var}',severity:'5',id:'958291',tag:'RULE_MATURITY/5',
tag:'RULE_ACCURACY/7',tag:'https://www.owasp.org/index.php/ModSecurity_CRS_RuleID-%{tx.id}',
tag:'PROTOCOL_VIOLATION/INVALID_HREQ',
tag:'http://www.bad-behavior.ioerror.us/documentation/how-it-works/',
setvar:'tx.msg=%{rule.msg}',setvar:tx.id=%{rule.id},
setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},
setvar:tx.protocol_violation_score=+%{tx.notice_anomaly_score},
setvar:tx.%{rule.id}-PROTOCOL_VIOLATION/INVALID_HREQ-%{matched_var_name}=%{matched_var}"

Reiniciar Apache y ¡problema resuelto!

La explicación a todo

Erradicar un error pero no encontrarle la explicación lógica es como estar co….

(por si no se entendió mi metáfora: lo anterior fue un ejemplo de algo que te deja con una sensación de discontinuidad y por consiguiente, de algo inconcluso xD)

Así que para no quedarme con esa asquerosa sensación, a pesar de haber resuelto el problema, seguí analizando lo sucedido hasta hallar respuestas y el tema es así:

  • En el archivo de reglas de OWASP, las líneas previas a la regla que se comentó, explicaban de manera abreviada, que la misma era en cumplimiento con lo establecido en las definiciones RFC 2616 (correspondiente a la definición de estándares del protocolo HTTP 1.1);
  • Los estándares HTTP están publicados nada más ni nada menos que por la W3C;
  • En dicha RFC, la sección 14.35.1 se refiere a los rangos de bytes que el cliente (navegador en este caso) envía en los campos de cabecera al servidor (a.k.a «headers» para los amigos). Es decir que la sección 14.35.1 de las RFC 2616 son las que definen los estándares para los rangos de bytes enviados por el cliente al servidor a través de las cabeceras HTTP;
  • Estas especificaciones, dicen claramente que: «si un rango de bytes sintácticamente válido, cuyo primer byte del rango sea menor a la longitud total del elemento a ser servido, o por lo menos, el sufijo del intervalo es distinto que cero, entonces la solicitud puede ser satisfecha por el servidor, pero de lo contrario, el servidor debe rechazar la petición«;

Si volvemos a darle un vistazo al error que ModSecurity grabó en los logs, veremos esto:

ModSecurity: Access denied with code 403 (phase 2).
String match "<strong>bytes=0-</strong>" at REQUEST_HEADERS:Range

El valor recibido indicaba un rango inválido en el cual, faltaba el sufijo del rango:

bytes=0-???

Recordemos que ese error, se producía al intentar acceder desde Google Chrome o desde su fork libre Chromium, al archivo de audio ogg. Es decir, que tanto Google Chrome como Chromium, envían como valor de rango de bytes en los encabezados HTTP, un rango inválido (sin sufijo). Dicha solicitud VIOLA LOS ESTÁNDARES DE LAS RFC 2616.

Vale aclarar que:

  1. A raíz de esto, revisando los logs, me di cuenta que el reclamo realizado por muchos usuarios que eran rechazados al intentar descargar un PDF desde dispositivos con Android, también era a causa de este problema. Vale decir que Android tampoco cumple con dichos estándares.
  2. A pesar de haberme enojado con MpdSecurity, no se puede responsabilizar del bloqueo a las reglas de OWASP ni mucho menos a ModSecurity, puesto que es el Software de Google quien al incumplir con dichos estándares provoca que sus aplicaciones actúen de forma similar a como lo haría una herramienta pensada para el ataque.

Lamentablemente, por la irresponsabilidad de Google, la única solución (que en realidad sería utilizar Mozilla Firefox), fue comentar la regla mencionada.

Happy Hacking, Fuckin’ Google!

Dedicado con todo googlelove a mi compañero Debish 😛

7 ideas sobre “Problemas al reproducir Ogg bajo Apache con ModSecurity desde Chrome y Chromium”

Los comentarios están cerrados.

Sentimos molestarte con lo de las Cookies, pero es por imperativo legal. Puedes ver aquí la Política de Cookies, si continúas navegando te informo que la estás aceptando ;)    Ver
Privacidad