Veracode的“不正确的资源关闭或释放”错误,为什么?

时间:2017-11-13 11:17:18

标签: c# .net-core veracode

这段代码有什么问题?此外,我该如何解决?

public class BodyStreamMiddleware
{
    private readonly RequestDelegate _next;

    public BodyStreamMiddleware(RequestDelegate next) { _next = next; }

    public async Task Invoke(HttpContext context)
    {
        //  Replace the FrameRequestStream with a MemoryStream.
        //  This is because the MemoryStream is rewindable, the FrameRequestStream is not.
        //  This allows ExceptionFilters to read the body for logging purposes
        string bodyAsText;
        using (var bodyReader = new StreamReader(context.Request.Body))
        {
            bodyAsText = bodyReader.ReadToEnd();
        }
        var bytesToWrite = Encoding.UTF8.GetBytes(bodyAsText);

        using (var memoryStream = new MemoryStream())
        {
            memoryStream.Write(bytesToWrite, 0, bytesToWrite.Length);
            memoryStream.Seek(0, SeekOrigin.Begin);
            context.Request.Body = memoryStream;


            //  Tell ASP.NET core to dispose the memory stream when the request ends 
            // (only added in desperation)
            context.Response.RegisterForDispose(memoryStream);
            await _next.Invoke(context);
        }
    }
}

当我在上面运行Veracode扫描时,它给了我

  

404不正确的资源关闭或发布

我知道下游进程可以获取对内存流的引用并挂起它,但是看不出它与默认的asp.net行为有什么不同(即有些东西可以抓住FrameRequestStream)。 / p>

2 个答案:

答案 0 :(得分:1)

为了别人的利益回答我自己的问题......

我设法通过以不同的方式重新读取请求流来修复/避开此问题。这让Veracode感到高兴,尽管我完全不相信以前的代码有任何问题。

坚持你的启动课......

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    ...
    app.Use(async (context, next) => {
        context.Request.EnableRewind();
        await next();
    }
    ...
});

我在这里写了https://needhack.wordpress.com/2018/01/17/make-the-request-stream-re-readable-in-asp-net-core-with-c/的博客,因为我们都被告知博客,因为如果我们这样做,我们将成为下一个Scott Hanselman,提高我们的费率并放弃每日通勤,对吗?

答案 1 :(得分:0)

这是Veracode中的问题。每当您在using块内使用异步操作时,都会出现问题。

在下面的示例中,DoWork很好。 DoWorkAsync被标记为发行不当。

    public static byte[] DoWork()
    {
        var buffer = new byte[10];
        using (var stream = new MemoryStream())
        {
            for (int i = 0; i < 10; i++)
            {
                stream.Write(buffer, i, 1);
            }

            return stream.ToArray();
        }
    }

    public static async Task<byte[]> DoWorkAsync()
    {
        var buffer = new byte[10];
        using (var stream = new MemoryStream())
        {
            for (int i = 0; i < 10; i++)
            {
                await stream.WriteAsync(buffer, i, 1);
            }

            return stream.ToArray();
        }
    }

此外,每次扫描似乎只能识别一次此问题。当您尝试弄清楚为什么标记了一个using块而没有标记出其他块时,这会导致更加混乱。您可以通过注释掉标记的块并再次运行扫描,然后在另一个using块上标记相同的问题来证明这一点。

如果您查看Stack Overflow,就会发现Veracode在涉及异步C#时经常产生误报。我建议您尽一切可能将其标记为误报缓解或通过设计缓解,并且不要为扫描错误而更改完全有效的代码。