🔥Adquiere tu membresía:  acceso a todos los cursos, videos eliminados, contenidos protegidos, manuales y más. >> Ver Más

Vulnerabilidad crítica en Python afecta a miles de programas

El módulo ipaddress de la biblioteca estándar de Python sufre una vulnerabilidad crítica de validación de la dirección IP. Esta vulnerabilidad es idéntica a la vulnerabilidad reportada en la biblioteca “netmask” (máscara de red) a principios de este año.

Los investigadores que descubrieron la vulnerabilidad crítica en la máscara de red, también descubrieron la misma vulnerabilidad en este módulo de Python. Ellos han identificado la vulnerabilidad como CVE-2021-29921.

La vulnerabilidad afecta concretamente al módulo ipaddress de Python 3.x y se debe a un cambio que realizaron en 2019.

Los ceros iniciales eliminados de las direcciones IP

Hace unos meses no enteramos por primera vez sobre una vulnerabilidad crítica de validación de IP en la   biblioteca de máscara de red utilizada por miles de aplicaciones.

La vulnerabilidad, identificada como CVE-2021-28918 (Crítica), CVE-2021-29418 (Media) y CVE-2021-29424 (Alta) existía en las versiones npm y Perl de la máscara de red. Esta vulnerabilidad también estaba presente en algunas otras bibliotecas similares.

Ahora resulta que la   biblioteca estándar ipaddress introducida en Python 3.3 también se ve afectada por esta vulnerabilidad. La vulnerabilidad la revelaron esta semana Victor Viale, Sick Codes, Kelly Kaoudis, John Jackson y  Nick Sahler y ha sido identificada como CVE-2021-29921. Esta se refiere a la interpretación incorrecta de direcciones IP por parte de la   biblioteca estándar ipaddress.

El módulo ipaddress de Python proporciona a los desarrolladores funciones para crear fácilmente direcciones IP, redes e interfaces. Además, permite analizar/normalizar direcciones IP ingresadas en diferentes formatos.

La  ipaddress de la biblioteca estándar de Python se utiliza para normalizar o interpretar direcciones IP en diferentes formatos.

Una dirección IPv4 se puede representar en una variedad de formatos, incluidos decimal, entero, octal y hexadecimal. No obstante, las direcciones IPv4 más comunes se expresan en formato decimal.

Por ejemplo, la dirección IPv4 104.20.59.209 está representada en formato decimal, empero, la misma se puede expresar en formato octal como 0150.0024.0073.0321.

Supongamos que recibes una dirección IP en formato decimal, 127.0.0.1, que se conoce ampliamente como la dirección de bucle invertido local o localhost.

Si tuvieras que anteponerle un 0, ¿debería una aplicación entenderla como 0127.0.0.1 como 127.0.0.1 o algo más?

Pruebas

Puedes probar esto en tu navegador web. En nuestras pruebas, al escribir 0127.0.0.1/ en la barra de direcciones de Chrome, el navegador interpreta la cadena completa como una dirección IP en   formato octal.

Al presionar Enter, la IP de hecho cambia a su equivalente decimal de 87.0.0.1. Esta es la manera como se supone que la mayoría de las aplicaciones administran direcciones IP tan ambiguas. 

La mayoría de los navegadores web como Chrome compensan automáticamente las direcciones IP de formato mixto.

De particular interés es el hecho de que 127.0.0.1 no es una dirección IP pública sino una dirección de loopback. Sin embargo, su representación ambigua la cambia a una dirección IP pública que conduce a un host completamente diferente.

De acuerdo con  la especificación original de IETF, para direcciones IP ambiguas, partes de una dirección IPv4 se pueden interpretar como octal si tienen el prefijo “0”.

Pero, en el caso de ipaddress de la biblioteca estándar de Python, los ceros iniciales simplemente se eliminarían y descartarían.

Una prueba de concepto realizada por Sick Codes y Victor Viale muestra que la biblioteca ipaddress de Python simplemente descartaría los ceros iniciales.

En otras palabras, cuando el módulo ipaddress es interpretado por Python, ‘010.8.8.8’ sería tratado como ’10 .8.8.8′, en lugar de ‘8.8.8.8’.

La ipaddress  de Python  interpreta ‘010.8.8.8’ como ’10 .8.8.8 ‘en lugar de ‘8.8.8.8’

“La validación de entrada incorrecta de cadenas octales en Python 3.8.0 a través stdlib ipaddress permite a un atacante remoto no autenticado realizar tareas indeterminadas en muchos programas que se basan en Python stdlib ipaddress. Por ejemplo, Falsificación de Petición del lado del servidor (SSRF), la inclusión de archivos remotos (RFI), y los ataques de inclusión de archivo local (LFI)”,

Por ejemplo, si una lista de bloqueo de evasión anti-SSRF dependiese de ipaddress de Python para analizar una lista de direcciones IP, habría problemas. Las direcciones IP ambiguas podrían introducirse fácilmente y hacer que las protecciones contra anti-evasión fueran inútiles.

Vulnerabilidad de regresión introducida en 2019

Aunque el   módulo ipaddress se introdujo en Python 3.3, esta vulnerabilidad de regresión se introdujo en el módulo a partir de la versión 3.8.0. El modulo está presente hasta la versión 3.10 de Python, según los investigadores.

Antes de v3.8.0a4, la ipaddress de Python tenía algunas comprobaciones que rechazaban las direcciones IP proporcionadas en formatos mixtos por completo. Es decir, octal y decimal:

Las versiones de Python anteriores a 3.8.0a4 no permitían direcciones IP en formatos ambiguos/mixtos

Sin embargo, como lo comprobamos, a partir de la versión 3.8.0a4 de Python, estas comprobaciones se eliminaron por completo.

“Dejamos de rechazar los octetos IPv4 por ser ambiguamente octales. Los ceros iniciales se ignoran y ya no se supone que especifiquen octetos octales. Los octetos son siempre números decimales. Los octetos no deben tener más de tres dígitos, incluidos los ceros iniciales”.

Joel Croteau – programador que anunció el cambio

Esto generó una discusión del porque los programadores de Python hicieron esto y las razones detrás de este cambio. Muchos querían conocer razones prácticas para la introducción de este cambio a la hora de gestionar las direcciones IP ambiguas.

Aunque las discusiones sobre un próximo parche están en curso, los detalles exactos sobre qué versión de Python lo contendrá son confusos.

En su lugar, uno de los programadores de Python sugirió un enfoque diferente:

“Es poco común interpretar direcciones IPv4 con ceros a la izquierda”.

Si desea admitir ceros a la izquierda, no tienes que modificar la ipaddress [sic] para eso, puedes preprocesar tus entradas. Esto funciona en cualquier versión de Python con o sin la corrección. Esto según lo dicho por el programador de Python, Victor Stinner, quien estaba proponiendo una solución alternativa al problema:

Una posible solución alternativa para la validación de la dirección IP propuesta por Stinner

Joel Croteau, Christian Heimes y Victor Stinner de Python siguen discutiendo sobre cuál es la mejor manera de abordar este problema.

Los hallazgos técnicos detallados de los investigadores los han proporcionado en una publicación en su blog.

Deja un comentario

Adquiere tu Membresía Anual Wiser

Adquiere tu Membresía Anual Wiser y adquiere grandes beneficios

Más información