我正在使用 klocwok 来查看我的代码。对于给定的代码行:
byte sigToVerify = new byte[sigFileInputStream.available()];
我收到以下错误报告:
SV.DOS.ARRSIZE:
sigFileInputStream.available()
用于数组大小的未经验证的用户输入 - 攻击者可以指定一个很大的数字,从而导致服务器上的高资源使用和 DOS 攻击
请帮我解决这个问题。
我正在使用 klocwok 来查看我的代码。对于给定的代码行:
byte sigToVerify = new byte[sigFileInputStream.available()];
我收到以下错误报告:
SV.DOS.ARRSIZE:
sigFileInputStream.available()
用于数组大小的未经验证的用户输入 - 攻击者可以指定一个很大的数字,从而导致服务器上的高资源使用和 DOS 攻击
请帮我解决这个问题。
如果没有更多的代码片段可以继续,我认为 Klocwork 在这里报告了一个有效的问题。您应该查看为SV.DOS.ARRSIZE检查器提供的文档,其中解释了报告此问题的原因。关于漏洞和风险:
应用程序外部数据的使用必须在应用程序使用之前进行验证。如果此数据用于在应用程序中分配对象数组,则必须仔细检查数据的内容。攻击者可以利用此漏洞强制应用程序分配大量对象,从而导致应用程序服务器上的资源使用率很高,并可能出现拒绝服务 (DoS) 情况。
关于缓解和预防:
可以通过验证来自应用程序外部的任何和所有输入(用户输入、 文件输入、系统参数等)来防止来自用户输入的 DoS 攻击。验证应包括长度和内容。...还应检查用于分配的数据的合理值,假设用户输入可能包含非常小或非常大的值。
甚至 Java InputStream API文档(其中 FileInputStream 是一个子类)警告说使用方法的返回值available()
是一个坏主意:
请注意,虽然 InputStream 的某些实现会返回流中的字节总数,但许多不会。使用此方法的返回值来分配旨在保存此流中所有数据的缓冲区是不正确的。
如何修复代码以避免这种情况的一个示例是,如上所述,available()
在使用它分配数组之前验证返回的值:
int buffSize = sigFileInputStream.available();
if (buffSize > 0 && buffSize < 100000000) { // 100MB
byte sigToVerify = new byte[buffSize];
// do something with sigToVerify ...
} else {
// error
}
请注意,sigToVerify
对于您的目的而言,100000000 或 100MB 可能仍然太大,也可能太小。您应该根据您的代码试图完成的任务来确定此处使用的最合理的值。