¿Java tiene desbordamientos de búfer?

96

¿Java tiene desbordamientos de búfer? Si es así, ¿puede darme escenarios?

ecleel
fuente
2
Se sabe que algunas funciones de la biblioteca (implementadas en código nativo) tienen errores. Especialmente en el área de Java 5 se conocen muchos exploits en 2D, perfiles de sonido o color.
eckes

Respuestas:

108

Dado que las cadenas de Java se basan en matrices de caracteres y Java comprueba automáticamente los límites de la matriz, los desbordamientos de búfer solo son posibles en escenarios inusuales:

  1. Si llama al código nativo a través de JNI
  2. En la propia JVM (generalmente escrito en C ++)
  3. El intérprete o compilador JIT no funciona correctamente (comprobaciones de límites obligatorias del código de bytes de Java)
Michael Borgwardt
fuente
24

Los lenguajes administrados como Java y C # no tienen estos problemas, pero las máquinas virtuales específicas (JVM / CLR / etc.) que realmente ejecutan el código sí pueden.

Brian Rasmussen
fuente
5
C # en un contexto inseguro puede tener desbordamientos de búfer. Java como lenguaje prohíbe completamente esto (debe cambiar los idiomas a través de JNI para obtener acceso de puntero no administrado)
ShuggyCoUk
1
Buen punto. Con C # inseguro, obviamente ya no estás en un espacio aislado en un mundo administrado cómodo.
Brian Rasmussen
1
Correcto, e incluso si USTED no escribe nada inseguro o no realiza ninguna interoperabilidad, podría estar usando una biblioteca que sí lo haga. Así que eso es algo a tener en cuenta.
BobbyShaftoe
13

Para todos los efectos, no.

Java tiene una verificación de límites de matriz que verificará que no se pueda acceder a los datos desde un área fuera de la matriz asignada. Cuando uno intenta acceder a un área que está más allá del tamaño de la matriz, se ArrayOutOfBoundslanzará una excepción.

Si hay un desbordamiento del búfer, probablemente se deba a un error en la Máquina virtual Java y, que yo sepa, no es el comportamiento previsto que está escrito en las Especificaciones del lenguaje Java ni en las Especificaciones de la máquina virtual Java.

coobird
fuente
10

Si y no. No, en el sentido de que realmente no puede crear por error abrirse a una vulnerabilidad de desbordamiento de búfer porque es un modelo de memoria administrada. Sin embargo, puede haber vulnerabilidades de desbordamiento de búfer en JVM y JDK. Vea este aviso de Secunia:

http://secunia.com/advisories/25295

O vea estos viejos avisos sobre varias vulnerabilidades JDK y JRE anteriores:

  • Las vulnerabilidades de desbordamiento de búfer y enteros en el entorno de ejecución de Java (JRE) "unpack200" La utilidad de desempaquetado de JAR puede llevar a la escalada de privilegios https://download.oracle.com/sunalerts/1020225.1.html

    Las vulnerabilidades de desbordamiento de búfer y enteros en Java Runtime Environment (JRE) con subprogramas de desempaquetado y aplicaciones Java Web Start que utilizan la utilidad de desempaquetado de JAR "unpack200" pueden permitir que un subprograma o aplicación que no sea de confianza escale privilegios. Por ejemplo, un subprograma que no es de confianza puede concederse a sí mismo permisos para leer y escribir archivos locales o ejecutar aplicaciones locales a las que puede acceder el usuario que ejecuta el subprograma que no es de confianza.

    Sun agradece a "regenrecht" que trabaja con iDefense VCP ( http://labs.idefense.com/vcp/ ) y Chris Evans de Google por informarnos sobre estos problemas.

  • Se han identificado varias vulnerabilidades en Sun Java Development Kit (JDK) y Java Runtime Environment (JRE). https://security.gentoo.org/glsa/200705-23

    El equipo de seguridad de Fujitsu informó de una vulnerabilidad no especificada que implica un "uso incorrecto de clases de sistema". Además, Chris Evans del equipo de seguridad de Google informó un desbordamiento de enteros que resultó en un desbordamiento de búfer en el analizador ICC utilizado con archivos JPG o BMP, y una llamada open () incorrecta a / dev / tty al procesar ciertos archivos BMP.

BobbyShaftoe
fuente
9

Un desbordamiento de búfer en el sentido estricto de sobrescribir la pila o el montón en sí requeriría:

  1. Un error en el marco (estos han existido en el pasado y pueden volver a hacerlo)
  2. El uso de JNI (esencialmente ya no usa código administrado)

Un desbordamiento de búfer en el sentido de que tiene un código que usa un búfer y su código es responsable de analizarlo correctamente, pero es posible que no lo haga. Por ejemplo, puede escribir un analizador XML y alguien podría proporcionarle una solicitud mal formada (o legítima pero poco común) que, debido al diseño de su analizador, sobrescribe los datos previamente validados con alguna carga útil que haría que su aplicación se comporte mal.

Esta última forma es menos probable, pero una función de limpieza de cadenas SQL mal escrita ampliamente distribuida que tuviera un problema como este sería un objetivo atractivo.

ShuggyCoUk
fuente
4

Las máquinas virtuales Java (y .Net) capturan código que intenta escribir fuera de la memoria reservada. Las aplicaciones que no manejan esto correctamente aún pueden causar problemas de seguridad. Si los usuarios malintencionados pueden activar excepciones al ingresar datos no válidos, pueden realizar ataques de denegación de servicio, por ejemplo.

Mendelt
fuente
3

Como ya se ha señalado, Java tiene, como lenguaje, control de límites en todos los accesos a la memoria, y si hay un error aquí, la JVM tiene la culpa y no el programa. Sin embargo, lo que debe tenerse en cuenta, que es un argumento similar a las pérdidas de memoria en Java; si bien no es posible romper la pila, una ArrayOutOfBoundsException en el lugar equivocado, que no se maneja correctamente, puede terminar arruinando su sistema.

falstro
fuente
3

Posiblemente podría causar un desbordamiento del búfer en un programa Java si estuviera utilizando la función Java Native Interace (JNI) para invocar código externo y el código externo tuviera un problema explotable. Esto es bastante poco común, ya que la mayoría de las aplicaciones evitan el uso de JNI siempre que sea posible.

Tim Howland
fuente
3

Es posible que un método escriba en entradas válidas de una matriz que no pretendía, normalmente a través de un desbordamiento de enteros.

Por ejemplo, lo siguiente no es suficiente para verificar los límites:

/* !! WRONG !! */ 0 <= off && 0 <= len && off+len <= buff.length /* !! WRONG !! */

IIRC, StringBufferuna vez tuvo un error como ese, pero no había nada interesante que pudieras hacer con él.

Tom Hawtin - tackline
fuente
¿Qué es suficiente para comprobar los límites?
Broam
1
@Broam: 0 <= off && 0 <= len && off <= buff.length-lenCreo. No me cites. Se ve igual pero no hay desbordamiento posible (en el original off + len podría volverse negativo y, por lo tanto, obviamente más pequeño que la longitud de la matriz). Asegúrese de que ningún programador de mantenimiento lo "arregle" en la forma obvia. Encuentro el desbordamiento de enteros enormemente confuso. Tengo que pensarlo durante un tiempo, y luego surge la persistente sospecha de que me he equivocado. Pero, por supuesto, debería haber otro revisor y el programador original; ¡juntos, por supuesto, no hay forma de que un error pueda pasar! (no)
Tom Hawtin - tackline
Tuve que mirar esto un poco, pero tienes razón. off + len podría desbordarse y ajustarse ... en C. En Java , a menos que me equivoque, obtendría una excepción de desbordamiento antes de que ocurriera, ¿verdad?
Broam
1
No. La aritmética de enteros se envuelve silenciosamente. C # tiene un "modo" en el que se lanza una excepción en caso de desbordamiento, pero no creo que se use mucho (si piensa usarlo, probablemente pensaría en hacer las cosas correctas de todos modos).
Tom Hawtin - tackline
1

Una de las características clave de JAVA es la seguridad. Los programas escritos en lenguajes interpretados no son propensos a la vulnerabilidad de desbordamiento del búfer, pero siempre puede causar un desbordamiento del búfer en el propio Interpreter. Aunque será difícil. De manera similar, Python también es un lenguaje interpretado y está a salvo del desbordamiento del búfer.

ABHISHEK SRIVASTAVA
fuente