【问题标题】:Veracode CWE ID 416: Use After FreeVeracode CWE ID 416:免费后使用
【发布时间】:2021-11-04 05:54:48
【问题描述】:

如何修复免费后使用 Veracode (CWE ID 416)

Veracode 的建议:确保所有指针在它们指向的内存被释放后都设置为 NULL。

错误指向:第 8 行“返回结果;”

+ (NSData *)dataFromBase64String:(NSString *)aString
{
    NSData *data = [aString dataUsingEncoding:NSASCIIStringEncoding];
    size_t outputLength = 0;
    void *outputBuffer = NewBase64Decode([data bytes], [data length], &outputLength);
    NSData *result = [NSData dataWithBytes:outputBuffer length:outputLength];
    free(outputBuffer);
    return result;
}

【问题讨论】:

  • outputBuffer=NULL;free(outputBuffer); 之后
  • @OlSen 你的意思是说 if (outputBuffer != NULL) { free(outputBuffer); } ?但是他们在“返回结果”上指出了错误;
  • 您的解释也可以。因为如果它 outputBuffer 不是 NULL 它需要再次空闲。结果必须返回,你不能在你返回之前释放它但是你可以返回 nil 如果 ouputBuffer==NULL
  • 你有理由相信这个工具知道它在说什么(特别是它指向哪条线?)从你对这个工具的问题来看,听起来正确的方法是打开支持使用 Veracode 的票证。我怀疑他们的工具坏了。
  • @OlSen 我尝试了您提到的上述解决方案,但没有通过 veracode 的扫描报告。你能指导我现在如何解决它吗?

标签: ios objective-c veracode


【解决方案1】:

Veracode 扫描只是帮助您在代码中找到可以改进与安全相关的编码的地方。当然,它并不能阻止攻击,但如果您的应用程序确实非常注重安全性,您可能会更难以读取处理后留下的内存。

Veracode 日志中的“错误”这个词可能有点过度使用..
但我对 Veracodes Error pointed on: Line 8 "return result;" 的建议是..

+ (NSData *)dataFromBase64String:(NSString *)aString
{
    if (aString!=nil && [aString length]) {
        size_t outputLength = 0;
        void *outputBuffer = NULL;
        NSData *data = [aString dataUsingEncoding:NSASCIIStringEncoding];
        outputBuffer = NewBase64Decode([data bytes], [data length], &outputLength);
        if (outputBuffer==NULL) return nil; //if NewBase64Decode() failed there is nothing to free..
        NSData *result = [NSData dataWithBytes:outputBuffer length:outputLength];
        free(outputBuffer);
        outputBuffer = NULL;
        return result;
    }
    return nil;
}

这是因为 free'd 的内存没有在你的意图下被设置为 NULL,所以有人在内存中扫描剩余的内存可能会找到一些关于地址以前内容的线索。

here 一些很好的讨论,如果真的需要释放后的 NULL。

如果您为了避免任何风险而进行了如此详细的说明,那么您甚至可以在使用它之前使用 NULL (void* outputBuffer = NULL;) 启动 outputBuffer。

好吧,如果这对于某些 objC 代码来说有点过头了,而 swizzling 可以覆盖整个方法,那就另当别论了。

编辑:更多的意大利面条代码,试图避免返回除 void 之外的任何值并改为更改传递的参数。

+ (void)dataFromBase64String:(NSString *)aString toResult:(NSData**)result
{
    if (aString!=nil && [aString length]) {
        size_t outputLength = 0;
        void *outputBuffer = NULL;
        NSData *data = [aString dataUsingEncoding:NSASCIIStringEncoding];
        outputBuffer = NewBase64Decode([data bytes], [data length], &outputLength);
        if (outputBuffer==NULL) return; //if NewBase64Decode() failed there is nothing to do
        *result = [NSData dataWithBytes:outputBuffer length:outputLength];
        free(outputBuffer);
        outputBuffer = NULL;
    }
}

//and call like..
NSData *myresult = nil;
[YOURCLASS dataFromBase64String:@"someString" toResult:&myresult];
NSLog(@"result=%@",myresult);

现在我想知道 Veracode 通过上面的编辑报告了什么..

【讨论】:

  • 感谢您的回答。我尝试了相同的答案并使用 Veracode 重新扫描了我的代码,但它们的结果仍然相同。他们指向您提到的上述代码中的第 13 行“}”。您能否建议我们在这里做错了什么?
  • 这就是@RobNapier 指出的。将基本返回报告为“错误”,这只是在离开方法块后触发已用堆栈的释放,这就是我所说的误导性的 Veracode 过度行为。我建议忽略那个“错误”。但它也应该报告第 8 行。可能根本就认为 NSData 的返回是有风险的,那么您可以返回 void 并直接更改传递的参数,就像在 NewBase64Decode 中为 outputLength 所做的那样。
猜你喜欢
  • 1970-01-01
  • 2021-11-06
  • 1970-01-01
  • 2020-01-14
  • 1970-01-01
  • 1970-01-01
  • 2018-07-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多