102

Java有缓冲区溢出吗?如果是,你能给我一些场景吗?

4

10 回答 10

116

由于 Java 字符串基于 char 数组并且 Java 会自动检查数组边界,因此缓冲区溢出仅在不寻常的情况下可能发生:

  1. 如果通过 JNI 调用本机代码
  2. 在 JVM 本身中(通常用 C++ 编写)
  3. 解释器或 JIT 编译器无法正常工作(Java 字节码强制边界检查)
于 2009-01-26T13:10:01.603 回答
29

Java 和 C# 等托管语言不存在这些问题,但实际运行代码的特定虚拟机(JVM/CLR/等)可能存在这些问题。

于 2009-01-26T13:01:23.007 回答
14

出于所有意图和目的,不。

Java 有数组边界检查,它将检查不能从分配的数组之外的区域访问数据。当尝试访问超出数组大小的区域时,ArrayOutOfBounds将引发异常。

如果存在缓冲区溢出,它可能来自 Java 虚拟机中的错误,并且据我所知,这不是 Java 语言规范或 Java 虚拟机规范中所写的预期行为。

于 2009-01-26T13:02:32.693 回答
10

是和不是。不,因为它是一个托管内存模型,所以您不能真正错误地创建自己的缓冲区溢出漏洞。但是,JVM 和 JDK 中可能存在缓冲区溢出漏洞。请参阅此 Secunia 咨询:

http://secunia.com/advisories/25295

或者查看这些关于以前几个 JDK 和 JRE 漏洞的旧公告:

  • Java 运行时环境 (JRE)“unpack200”JAR 解包实用程序中的整数和缓冲区溢出漏洞可能导致权限升级https://download.oracle.com/sunalerts/1020225.1.html

    Java 运行时环境 (JRE) 中的整数和缓冲区溢出漏洞,带有解包小程序和使用“unpack200”JAR 解包实用程序的 Java Web Start 应用程序可能允许不受信任的小程序或应用程序提升权限。例如,不受信任的小程序可能会授予自己读取和写入本地文件或执行运行不受信任的小程序的用户可访问的本地应用程序的权限。

    Sun 衷心感谢“regenrecht”与 iDefense VCP ( http://labs.idefense.com/vcp/ ) 和 Google 的 Chris Evans 将这些问题提请我们注意。

  • Sun Java Development Kit (JDK) 和 Java Runtime Environment (JRE) 中发现了多个漏洞。https://security.gentoo.org/glsa/200705-23

    富士通安全团队报告了一个涉及“不正确使用系统类”的未指定漏洞。此外,来自 Google 安全团队的 Chris Evans 报告了整数溢出,导致用于 JPG 或 BMP 文件的 ICC 解析器中的缓冲区溢出,以及在处理某些 BMP 文件时对 /dev/tty 的错误 open() 调用。

于 2009-01-26T13:03:11.287 回答
9

严格意义上的覆盖堆栈或堆本身的缓冲区溢出将需要:

  1. 框架中的一个错误(这些在过去已经存在并且很可能再次出现)
  2. JNI 的使用(本质上不再使用托管代码)

从某种意义上说,缓冲区溢出是您的代码使用缓冲区并且您的代码负责正确解析它但没有这样做是可能的。例如,您可能编写了一个 XML 解析器,并且有人可能会向您提供格式错误(或合法但不常见)的请求,由于您的解析器的设计会用某些有效负载覆盖先前验证的数据,这会导致您的应用程序表现不佳。

后一种形式不太可能,但是一个广泛分布的写得不好的 sql 字符串清理函数存在这样的问题,这将是一个诱人的目标。

于 2009-01-26T13:04:43.827 回答
4

Java(和 .Net)虚拟机捕获试图在保留内存之外写入的代码。不能正确处理此问题的应用程序仍会导致安全问题。例如,如果恶意用户可以通过输入无效输入来触发异常,他们可以进行拒绝服务攻击。

于 2009-01-26T13:08:46.643 回答
3

正如已经指出的那样,Java 作为一种语言,对所有内存访问进行了边界检查,如果这里出现错误,则说明 JVM 有问题,而不是程序有问题。但是,需要注意的是,这与 Java 中的内存泄漏类似;虽然无法粉碎堆栈,但在错误位置出现的 ArrayOutOfBoundsException 未正确处理,仍可能最终会搞砸您的系统。

于 2009-01-26T13:05:39.800 回答
3

如果您使用 Java Native Interace (JNI) 工具调用外部代码,并且外部代码存在可利用的问题,那么您可能会在 Java 程序中导致缓冲区溢出。这是相当少见的,因为大多数应用程序尽可能避免使用 JNI。

于 2009-01-26T13:24:37.907 回答
3

一种方法可能会写入它不打算写入的数组的有效条目,通常是通过整数溢出。

例如,以下内容不足以检查边界:

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

IIRC,StringBuffer曾经有过这样的错误,但你可以用它做任何有趣的事情。

于 2009-01-26T13:36:48.443 回答
1

JAVA 的关键特性之一是安全性。用解释性语言编写的程序不容易受到缓冲区溢出漏洞的影响,但您总是可以在解释器本身中导致缓冲区溢出。虽然会很困难。类似地,Python 也是一种解释型语言,可以避免缓冲区溢出。

于 2018-06-04T06:36:12.470 回答