6

我们在 ASP.Net 和 C# 中有一个遗留的 Web 应用程序,为此我们收到了大约 400 个由 Veracode 扫描引发的跨站点脚本缺陷。我创建了一个示例 Web 应用程序并模拟了这个问题,发现每当我们直接使用任何字符串输入时,它都会引发缺陷。这样做HttpUtility.HtmlEncode(TextBox1.Text);"可以满足验证码的要求,但是在所有 400 个位置应用此更改是不可行的,因为那样会有大量的工作和测试工作。我正在寻找某种方式在 httphandler 中实现一些插件,以便所有输入都在一个地方编码,我们不必在任何地方更改它。如果可以的话,有人可以指导我吗?即使您可以指导我进近,至少也足以有一个方向。提前谢谢了。

StringOps strop = new StringOps();
        string txt1, txt2;
        txt1 = HttpUtility.HtmlEncode(TextBox1.Text);
        txt2 = HttpUtility.HtmlEncode(TextBox2.Text);
        Response.Write(strop.Add(txt1, txt2));

如果我删除 HttpUtility.HTMLEncode 行 Veracode 会抱怨它。由于我们在很多地方都在做这个字符串操作,所以在任何地方实现这个都是不可行的。这是否有可能在一个地方实现这种编码,并且所有响应和请求都应该通过该管道,例如 HTTPHandler 和 HTTPModule。

4

2 回答 2

1

您可以使用HttpModule有条件地分配给HttpResponse.Filter拦截和处理HttpResponse.Write使用的自定义来完成此操作。


模块示例

此示例使用Content-Typerequest.Header 的值来确定是否应应用 html 编码。

public class FilterResponseWriteModule : IHttpModule, IDisposable
{
    private System.IO.Stream filterStream;


    public FilterResponseWriteModule()
    {
    }

    public void Init(HttpApplication context)
    {
        context.BeginRequest += Context_BeginRequest;
    }

    private void Context_BeginRequest(object sender, EventArgs e)
    {
        var context = (sender as HttpApplication).Context;


        if (ShouldApplyFilter(context.Request))
            ApplyFilter(context.Response);
    }

    private bool ShouldApplyFilter(HttpRequest request)
    {
        return string.Equals(request.ContentType, @"text/plain", StringComparison.OrdinalIgnoreCase);
    }

    private void ApplyFilter(HttpResponse response)
    {
        filterStream = new EncodeStreamFilter(response.Filter);
        response.Filter = filterStream;
    }

    public void Dispose()
    {
        if (filterStream != null)
        {
            filterStream.Dispose();
        }
    }
}

过滤流示例(封装和覆盖)

Stream 是一个抽象类,因此它将生成所有相关的覆盖方法存根。

public class EncodeStreamFilter : Stream, IDisposable
{
    private Stream _baseStream;

    public EncodeStreamFilter(Stream responseFilter)
    {
        _baseStream = responseFilter;            
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        byte[] bufferBlock = new byte[count];
        Buffer.BlockCopy(buffer, offset, bufferBlock, 0, count);

        var encodedBytes = Encoding.UTF8.GetBytes(HttpUtility.HtmlEncode(Encoding.UTF8.GetString(bufferBlock)));

        _baseStream.Write(encodedBytes, 0, encodedBytes.Length);
    }

    public override bool CanRead
    {
        get
        {
            return _baseStream.CanRead;
        }
    }

    public override bool CanSeek
    {
        get
        {
            return _baseStream.CanSeek;
        }
    }

    public override bool CanWrite
    {
        get
        {
            return _baseStream.CanWrite;
        }
    }

    public override long Length
    {
        get
        {
            return _baseStream.Length;
        }
    }

    public override long Position
    {
        get
        {
            return _baseStream.Position;
        }

        set
        {
            _baseStream.Position = value;
        }
    }

    public override void Flush()
    {
        _baseStream.Flush();
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        return _baseStream.Read(buffer, offset, count);
    }

    public override long Seek(long offset, SeekOrigin origin)
    {
        return _baseStream.Seek(offset, origin);
    }

    public override void SetLength(long value)
    {
        _baseStream.SetLength(value);
    }



    protected override void Dispose(bool disposing)
    {
        if (!disposing)
        {
            _baseStream.Dispose();
        }
        base.Dispose(disposing);
    }
}

将模块添加到 Web.Config

注意:在这种情况下,我将模块定义为我的应用程序的 App_Start 文件夹中的一个类。

<system.webServer>
    <modules>
        <add name="FilterResponseWriteModule" type="HttpModulesTestApp.App_Start.FilterResponseWriteModule"/>
    </modules>
</system.webServer>
于 2016-11-27T16:23:19.893 回答
0

听我在 asp.net 1.0 或 2.0 中也有一个旧站点。我们确实将其框架更改为 4.0。

因此,我的建议是更改其框架并运行冒烟测试,可能会出现一些问题,然后按预期解决,然后主要关注处理诸如 Response.Write 之类的事情。由于 ASP.net 现在是开源的,因此获取这些代码并对核心功能进行最小的更改并完成您的工作,尝试尽可能多地利用部分功能,或任何类似的东西,以便在不丢失更改的情况下进行升级。

于 2016-11-21T21:38:58.013 回答