Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handle cross site scripting flaw raised by veracode

We have a legacy web application in ASP.Net and C#, for which we are getting around 400 plus cross site scripting flaw raised by Veracode scan. I have created a sample web application and simulated the issue, and found that whenever we are using any string input directly its raising the flaw. Doing HttpUtility.HtmlEncode(TextBox1.Text);"satisfies the veracode, however applying this change in all 400 places is not feasible as then there would be huge amount of work and testing efforts. I am looking for someway to implement some plug in in httphandler so that all the inputs get encoded at one place and we don't have to change it everywhere. Can someone please steer me if this is possible if yes even if you can guide me on just on approach would be good enough to have a direction at least. Many thanks in advance.

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

If I remove the HttpUtility.HTMLEncode lines Veracode complains about it. Since there are so many places where in we are doing this string operations so implementing this everywhere is not feasible. Would this be possible to have this encoding implemented on a single place and all the response and request should go through that pipeline e.g. HTTPHandler and HTTPModule.

like image 623
Alok Avatar asked Nov 18 '16 14:11

Alok


1 Answers

You can accomplish this with a Custom HttpModule that conditionally assigns to HttpResponse.Filter to intercept and process HttpResponse.Write usage.


Module Example

this example uses the value of Content-Type of the request.Header to determine whether the html Encoding should be applied.

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();
        }
    }
}

Filter Stream Example (encapsulate and override)

Stream is an abstract class, so it will generate all relevant override method stubs.

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);
    }
}

Add Module to Web.Config

Note: In this case, I've defined the module as a class in the App_Start folder of my application.

<system.webServer>
    <modules>
        <add name="FilterResponseWriteModule" type="HttpModulesTestApp.App_Start.FilterResponseWriteModule"/>
    </modules>
</system.webServer>
like image 68
Brett Caswell Avatar answered Oct 05 '22 09:10

Brett Caswell