问题描述
我有一些代码可以从 Checkmarx 认为不受信任的源(我控制的文件)中检索数字数据,在某些时候我将其转换为一对整数,并使用这样的函数对它们进行范围检查,在访问两者之间的“不安全”缓冲区之前。
int ValidateInt(int value,int min,int max)
{
if(value < min) { throw new ArgumentOutOfRangeException("value",value,"Too small"); }
if(value > max) { throw new ArgumentOutOfRangeException("value","Too big"); }
return value;
}
void AccessBuffer(IntPtr buffer,int bufferLengthInInt32s,int lowerBound,int upperBound)
{
lowerBound = ValidateInt(lowerBound,bufferLengthInInt32s-1);
upperBound = ValidateInt(upperBound,bufferLengthInInt32s-1);
for(int index=lowerBound ; index<upperBound ; index++)
DoSomething(Marshal.ReadInt32(buffer,index*4));
}
问题是,它仍然让 Checkmarx 不高兴。事实上,在我用这个替换我更原始的验证(只检查下限与 0 和上限与长度)之后,它带来了更多“反序列化不受信任的数据”!
有什么方法可以让 Checkmarx 知道我们已经检查了整数,我们知道它们在哪个范围内,它们现在不再“不受信任”?
解决方法
整数验证应该已经被认可并且足够了,但我认为 Checkmarx 不会将其识别为消毒剂。您可以通过使用 Checkmarx Audit 覆盖 Deserializing Untrusted Data Checkmarx 查询来更改此行为。
Checkmarx 开箱即用的是对 ComputeHash 方法的调用。我建议从不同的 HashAlgorithm(s) 调用任何可用的 ComputeHash 方法(推荐使用强散列算法)替换您当前的整数检查
SHA256 hashAlgorithm = SHA256.Create();
var lowerBoundHash = hashAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(lowerBound));
var upperBoundHash = hashAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(upperBound));
//if (upperBoundHash != expectedUpperBoundHash) {}
//if (lowerBoundHash != expectedLowerBoundHash) {}
或者您可以简单地向您的安全团队指出,由于存在整数验证,因此应该将其标记为不可利用