La vulnerabilidad de Nginx que filtra la bóveda de Bitwarden
(labs.hakaioffsec.com)- Nginx, un servidor web multipropósito con una cuota de mercado dominante desde 2004
- Una configuración incorrecta de Nginx puede derivar en vulnerabilidades de seguridad y exposición de datos
- Presentación de NavGix, una herramienta automatizada para detectar vulnerabilidades en Nginx
- Esta vulnerabilidad puede permitir el acceso a archivos y directorios fuera del alcance previsto
- Los estudios de caso sobre Bitwarden y el HPC Toolkit de Google muestran la gravedad de esta vulnerabilidad
1 comentarios
Opiniones de Hacker News
Para referencia, gixy (inspector de configuración de nginx) detecta este problema: https://github.com/yandex/gixy/blob/master/docs/en/plugins/a...
Y NixOS ejecuta gixy automáticamente sobre las configuraciones generadas a través de él, y si hay un problema rechaza la compilación del sistema
$urien una redirección 301Pero me pregunto si existe un buscador de opciones mejor. No me gustó la forma de buscar entre miles de opciones; quisiera ver solo un paquete como
sshy únicamente las opciones correspondientes, pero se mezclan demasiados resultados irrelevantesPuede que sea una pregunta tonta, pero ¿hay alguna buena razón para que nginx deba permitir subir al directorio padre con
..en la ruta de una URL? Simplemente parece un comportamiento que está esperando causar problemasEdit: sigo algo confundido sobre lo que pasa en la vulnerabilidad original. Parece que http://localhost/foo../secretfile.txt se interpreta como algo como
/var/www/foo/../secretfile.txt, pero en un servidor sin vulnerabilidad, ¿por qué http://localhost/foo/../secretfile.txt no se interpretaría igual? No entiendo por qué..dentro de la ruta solo funciona a vecesEn este caso, nginx la interpreta como un directorio (http://localhost/foo) por la forma en que una parte de la URL se mapea al sistema de archivos local en la configuración. Como parece apuntar a un directorio, cuando nginx construye la ruta completa del recurso solicitado termina con
"${mapped_path}/../secretfile.txt", y aunque desde la perspectiva de la URL no tenga sentido, en el sistema de archivos local sí es válido. Una URL es solo una cadena, no un conjunto real de componentes de ruta, así que la ubicación de las barras tampoco es intrínsecamente importanteEs un problema muy común que se ha visto una y otra vez en servidores web desde que existe la web. La asignación directa de URLs a rutas de archivos se volvió popular porque empezó con servidores simples de archivos estáticos con índices, pero pronto pasó a entornos mixtos donde la URL ya no es una ruta sino un identificador de aplicación. Se indica la app con una parte de la ruta y el resto se trata como parámetros o argumentos
Y en general, respetar
.o..de una URL para objetos del sistema de archivos normalmente no tiene sentido. Mis apps normalizan la ruta solicitada para que se mapee correctamente. Los navegadores tratan la URL como una ruta al construir enlaces relativos, así que también hay que tener cuidado con cuándo y cómo usar una/final. Del lado del servidor podría apuntar a un recurso con un significado distintolocation, algo comoallow_parent_traversal on;"/foo/bar/.."para bloquearlo o normalizarlo a"/foo/". Pero"/foo/bar.."es un nombre de archivo completamente válido, así que parece esquivar esa comprobación y no lo detecta..en una ruta depende por completo de los permisos de archivosEn este caso, si suponemos que desde el directorio índice web (
../index.html) hay permiso para leer archivos hasta llegar al directorio raíz (/), entonces, una vez que se tiene permiso para subir hasta la raíz, también se puede ver cualquier archivo legible por todos y accesible desde ahí, por ejemplo/etc/passwdPiensa en un tenedor de tres puntas, donde el servidor web está en la punta de la derecha. Si la parte donde se unen las puntas es el sistema de archivos, cuando se tiene permiso de acceso a los archivos y directorios que conectan desde la punta derecha donde está el servidor web hasta ese mango común, una vez que llegas ahí puedes seguir accediendo a los archivos de las otras puntas
No entiendo por qué esto no se considera una vulnerabilidad de nginx. Este comportamiento es totalmente absurdo, no parece tener ningún propósito útil y es explotable de inmediato
También hay que recordar que nginx se volvió popular gracias a benchmarks donde parecía más “web scale” que Apache2
Me dan ganas de proponer esto: poner una opción parecida a una Linux capability para quitar la opción
..del parser de nombres de archivo del kernel de LinuxEn las apps web, desde la época de los módems telefónicos, no han dejado de aparecer distintas formas de meter los dos puntos para saltarse restricciones. Igual que Linux hizo con otras clases de bugs en espacio de usuario, ya va siendo hora de buscar una forma de cerrar este problema de una vez
RESOLVE_BENEATHen https://man7.org/linux/man-pages/man2/openat2.2.htmlFreeBSD tiene esta función en el
openat(2)normal comoO_RESOLVE_BENEATHBasta con ejecutar nginx como un usuario separado con privilegios muy limitados, o correrlo en Docker. Si además lo actualizas con regularidad, normalmente eso resuelve el 90% de los problemas de seguridad
/some/../pathdebería estar prohibido casi al 100%. No hay un caso de uso razonable más allá de “alguien escribió código feísimo”../some/pathal menos a veces sí tiene sentidoAun así, probablemente no sería tan útil como parece. Muchas apps interpretan
..antes de pasárselo al sistema operativoSi estás sirviendo archivos desde una carpeta hacia la web, el framework web debe encargarse de no salirse de la carpeta raíz pública que le toca. Si lo estás armando tú mismo, tienes que contemplar todo tipo de casos, incluido ese
Eso de que “el equipo de Google VRP dio una recompensa de 500 dólares por encontrar esta vulnerabilidad. Consideró que el impacto en la aplicación no era lo bastante serio como para dar una recompensa mayor”, ¿o sea que la exposición del correo de la cuenta de GCP y la clave privada vale solo 500 dólares? ¿Qué demonios? Muy de Google, la verdad
Menos mal que lo filtrado seguía cifrado. Ni siquiera una empresa especializada en este tipo de cosas está a salvo de filtraciones, así que, siendo sinceros, este es el mejor escenario posible
El título está bastante editado. El título original es Hunting for Nginx Alias Traversals in the wild
El título enviado a HN destaca la vulnerabilidad de Bitwarden, pero el artículo también cubre el caso de Google
Si uno solo necesita servir archivos estáticos de forma segura y estable usando la menor cantidad posible de recursos, ¿cuál sería hoy la mejor opción? Antes habría elegido Nginx, pero desde la perspectiva de seguridad me pregunto si no convendría más una herramienta más específica y con menos margen de configuración
Es multiplataforma, está escrito en Rust, su configuración es simple y trae valores seguros por defecto. También tiene imágenes de contenedor endurecidas y un módulo endurecido para NixOS
No recomiendo Caddy. La imagen oficial de Docker corre como root por defecto [1], y tampoco ofrece un archivo de unidad de systemd correctamente aislado [2]
[1]: https://github.com/caddyserver/caddy-docker/issues/104
[2]: https://github.com/caddyserver/dist/blob/master/init/caddy.s...
Edit: ajusté la redacción
file_serversólidoPuede que sea una pregunta tonta, pero ¿por qué Bitwarden permitía desde el inicio solicitudes no autenticadas a
/attachments? Aunque existiera el bug de Nginx, ¿no habría fallado la solicitud si esa URL hubiera requerido autenticación?Aun así, como distribuyeron una configuración riesgosa a través de Docker, sí es responsabilidad de Bitwarden. Parece que Bitwarden también lo reconoció y luego lo corrigió
Perdonen la pregunta tonta. ¿Tener la propiedad correcta de directorios y archivos no bloquea este tipo de recorrido?
Si nginx no se ejecuta como root, ¿cómo puede leer archivos distintos de los asignados explícitamente al usuario de nginx?
go-rwxa todos los archivos de la app y al grupo de los archivos “static” le asignaswww-datacon solog+r, entonces el servidor web no puede acceder a los archivos de la app.Literalmente es hosting de aplicaciones 101, y la gente ya hacía eso hace 20 años.
/home.Puede que tengas que ajustar un poco más las membresías de grupo, pero vale totalmente la pena.
Igual la estoy regando durísimo. Ay.
www-data. Si la aplicación genera datos sensibles, obviamente es mejor usar umask 077.Por desgracia, nginx y otros servidores web normalmente sí necesitan ejecutarse como root en aplicaciones web comunes, porque tienen que escuchar en los puertos 80 o 443. Solo root puede abrir puertos por debajo de 1024.
Aquí hay una explicación más detallada: https://unix.stackexchange.com/questions/134301/why-does-ngi...