java - java中stringbuilder中Fortify的拒绝服务问题

标签 java memory stringbuilder fortify

Fortify 客户端给出了字符串生成器的错误和建议,

问题代码:

StringBuilder sb=new StringBuilder();    
sb.append(request.getParameter("id"));
sb.append(request.getParameter("name"));
sb.append(request.getParameter("question"));
sb.append(request.getParameter("answer"));

强化错误:

用户控制的数据被附加到使用默认构造函数初始化的 StringBuilder 实例

将用户控制的数据附加到使用默认支持字符数组初始化的 StringBuilder 或 StringBuffer 实例 size (16) 会导致应用程序消耗大量堆内存,同时调整底层数组的大小以适应用户的 数据。当数据附加到 StringBuilder 或 StringBuffer 实例时,该实例将确定是否支持字符 数组有足够的可用空间来存储数据。如果数据不适合,StringBuilder 或 StringBuffer 实例将创建一个新的 容量至少是前一个数组大小的两倍的数组,并且旧数组将保留在堆中,直到它成为垃圾 集。攻击者可以使用此实现细节来执行拒绝服务 (DoS) 攻击。

强化推荐: 使用预期附加数据大小的初始容量初始化 StringBuilder 或 StringBuffer 以减少 调整后备数组大小的次数。在将数据附加到 StringBuilder 或 StringBuffer 实例之前检查数据的大小。

...
private final int BUFFER_CAPACITY = 5200;
StringBuilder sb = new StringBuilder(BUFFER_CAPACITY);
...
final String lineSeparator = System.lineSeparator();
String[] labels = request.getParameterValues("label");
for (String label : labels) {
if (label.length() + lineSeparator.length() + sb.length()<= sb.capacity()) {
sb.append(label).append(lineSeparator);
} else {
// Handle error
}
}

对问题陈述和建议的查询:

  1. 如果垃圾收集器释放它的内存,攻击者如何造成拒绝服务攻击?是否适用?

  2. 我要求在字符串生成器中存储 0 到 12000 个最大字符的动态数据范围, 所以如果我使用 12000 个字符来初始化字符串生成器,那么如果我的输入只有 100 字符串表示,剩余的 11900 长度的内存是不需要的。 那么在这种情况下,我真的需要在 String Builder 容量中设置最大字符吗? 或者我可以只使用默认构造函数对我的输入参数进行长度验证?

这个问题有什么更好的解决方案?

最佳答案

这是胡说八道。

其中可能存在相关问题,例如:

  • 输入数据很大(尽管它似乎来自请求 header ,因此上游应该已经受到限制)
  • 单个输入是空的,但有很多实例,这会为输入数据很少的合理值创建所有开销 - 因此,如果有任何可能不会分配大于默认初始容量的容量,请不要分配使用它!
  • 如果不小心,生成的字符串可能不明确或存在注入(inject)漏洞。

StringBuilder 至少会在当前缓冲区用尽时将容量翻倍以将成本摊销到 O(n)。 StringBuilder 可能比输入数据大。如果不将其转换为 String,部分原因可能是过度分配,可能是原始长度的两倍。原始文件通常是每个字符 1 个字节,但 Java 有 2 个字节的 char。如果输入被压缩,大小的爆炸可能会令人惊讶,特别是在多重压缩的情况下。

我建议尝试 DoSing 您自己的应用程序,尽管我发现很少有证据表明应用程序级 DoS 攻击在野外仍然很普遍。

关于java - java中stringbuilder中Fortify的拒绝服务问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72113314/

相关文章:

java - 无法在 Android 模拟器上 root

Java 过滤器列表仅包含不同的(比较器不会为任何值对返回 null)值

java 数组双端队列大小与性能

数组和指针版本在内存分配方面的比较

java - 无法重载 AIDL 接口(interface)中的方法

ios - swift : Does hiding an animating view still affect memory/performance?

java - SWT的虚拟表是否释放TableItems

java - 文件大小增加但文本未写入

c# - 使用 StringBuilder 以点格式保存 double

c# - 如何获取附加到 StringBuilder 的最后一个字符串?