Java有缓冲区溢出吗?如果是,你可以给我一些情景吗?
正如已经指出的那样,Java作为一种语言,必须检查所有内存访问,如果这里有错误,那么JVM就是错误而不是程序 . 但是,应该注意的是,这与Java中的内存泄漏类似;虽然不可能粉碎堆栈,但错误位置的ArrayOutOfBoundsException(未正确处理)可能仍然会导致系统崩溃 .
如果您使用Java Native Interace(JNI)工具来调用外部代码,并且外部代码存在可利用的问题,则可能会导致Java程序中的缓冲区溢出 . 这是相当罕见的,因为大多数应用程序尽可能避免使用JNI .
由于Java Strings基于char数组而Java自动检查数组边界,因此只有在不常见的情况下才能实现缓冲区溢出:
如果您通过JNI调用本机代码
在JVM本身(通常用C编写)
解释器或JIT编译器无法正常工作(Java字节码强制边界检查)
诸如Java和C#之类的托管语言没有这些问题,但实际运行代码的特定虚拟机(JVM / CLR / etc)可能会出现这些问题 .
出于所有意图和目的,没有 .
Java有数组bounds checking,它将检查无法从分配的数组之外的区域访问数据 . 当一个人试图访问超出数组大小的区域时,将抛出ArrayOutOfBounds异常 .
如果存在缓冲区溢出,则可能是来自Java虚拟机中的错误,据我所知,这不是Java语言规范和Java虚拟机规范中编写的预期行为 .
是的,不是 . 不,因为它是一个托管内存模型,你无法真正创建错误地打开缓冲区溢出漏洞 . 但是,JVM和JDK中可能存在缓冲区溢出漏洞 . 看到这个Secunia顾问:
http://secunia.com/advisories/25295
严格意义上的覆盖堆栈或堆本身的缓冲区溢出需要:
框架中的一个错误(这些错误在过去已经存在,可能会再次出现)
使用JNI(基本上不再使用托管代码)
缓冲区溢出在某种意义上说,你有使用缓冲区的代码,你的代码负责正确解析它但是没有这样做是可能的 . 例如,您可能会编写一个XML解析器,并且有人可能会向您提供格式错误(或合法但不常见)的请求,由于您的解析器的设计会覆盖先前验证的数据,其中某些有效负载会导致您的应用程序行为异常 .
后一种形式不太可能,但编写得很糟糕的sql字符串清理函数广泛分布,有一个问题,如这将是一个诱人的目标 .
Java(和.Net)虚拟机捕获尝试在保留内存之外写入的代码 . 无法正确处理此问题的应用程序仍可能导致安全问题 . 如果恶意用户可以通过输入无效输入来触发异常,则可以进行拒绝服务攻击 .
一个方法可能通常通过整数溢出来写入它不想要的数组的有效条目 .
例如,以下内容不足以检查边界:
/* !! WRONG !! */ 0 <= off && 0 <= len && off+len <= buff.length /* !! WRONG !! */
IIRC, StringBuffer 曾经有过这样的错误,但是没有任何有趣的东西可以用它做 .
StringBuffer
安全性是JAVA的一个关键特性 . 用解释语言编写的程序不容易出现缓冲区溢出漏洞,但是您总是可以在Interpreter本身中导致缓冲区溢出 . 虽然很难 . 类似地,Python也是一种解释型语言,并且不受缓冲区溢出的影响 .
10 回答
正如已经指出的那样,Java作为一种语言,必须检查所有内存访问,如果这里有错误,那么JVM就是错误而不是程序 . 但是,应该注意的是,这与Java中的内存泄漏类似;虽然不可能粉碎堆栈,但错误位置的ArrayOutOfBoundsException(未正确处理)可能仍然会导致系统崩溃 .
如果您使用Java Native Interace(JNI)工具来调用外部代码,并且外部代码存在可利用的问题,则可能会导致Java程序中的缓冲区溢出 . 这是相当罕见的,因为大多数应用程序尽可能避免使用JNI .
由于Java Strings基于char数组而Java自动检查数组边界,因此只有在不常见的情况下才能实现缓冲区溢出:
如果您通过JNI调用本机代码
在JVM本身(通常用C编写)
解释器或JIT编译器无法正常工作(Java字节码强制边界检查)
诸如Java和C#之类的托管语言没有这些问题,但实际运行代码的特定虚拟机(JVM / CLR / etc)可能会出现这些问题 .
出于所有意图和目的,没有 .
Java有数组bounds checking,它将检查无法从分配的数组之外的区域访问数据 . 当一个人试图访问超出数组大小的区域时,将抛出ArrayOutOfBounds异常 .
如果存在缓冲区溢出,则可能是来自Java虚拟机中的错误,据我所知,这不是Java语言规范和Java虚拟机规范中编写的预期行为 .
是的,不是 . 不,因为它是一个托管内存模型,你无法真正创建错误地打开缓冲区溢出漏洞 . 但是,JVM和JDK中可能存在缓冲区溢出漏洞 . 看到这个Secunia顾问:
http://secunia.com/advisories/25295
严格意义上的覆盖堆栈或堆本身的缓冲区溢出需要:
框架中的一个错误(这些错误在过去已经存在,可能会再次出现)
使用JNI(基本上不再使用托管代码)
缓冲区溢出在某种意义上说,你有使用缓冲区的代码,你的代码负责正确解析它但是没有这样做是可能的 . 例如,您可能会编写一个XML解析器,并且有人可能会向您提供格式错误(或合法但不常见)的请求,由于您的解析器的设计会覆盖先前验证的数据,其中某些有效负载会导致您的应用程序行为异常 .
后一种形式不太可能,但编写得很糟糕的sql字符串清理函数广泛分布,有一个问题,如这将是一个诱人的目标 .
Java(和.Net)虚拟机捕获尝试在保留内存之外写入的代码 . 无法正确处理此问题的应用程序仍可能导致安全问题 . 如果恶意用户可以通过输入无效输入来触发异常,则可以进行拒绝服务攻击 .
一个方法可能通常通过整数溢出来写入它不想要的数组的有效条目 .
例如,以下内容不足以检查边界:
IIRC,
StringBuffer
曾经有过这样的错误,但是没有任何有趣的东西可以用它做 .安全性是JAVA的一个关键特性 . 用解释语言编写的程序不容易出现缓冲区溢出漏洞,但是您总是可以在Interpreter本身中导致缓冲区溢出 . 虽然很难 . 类似地,Python也是一种解释型语言,并且不受缓冲区溢出的影响 .