Устранение ошибки межсайтового скриптинга, вызванной veracode

У нас есть устаревшее веб-приложение на ASP.Net и C #, для которого мы получаем около 400 с лишним ошибок межсайтового скриптинга, вызванных сканированием Veracode. Я создал образец веб-приложения и смоделировал проблему и обнаружил, что всякий раз, когда мы используем какой-либо строковый ввод напрямую, это вызывает ошибку. Выполнение 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.


person Alok    schedule 18.11.2016    source источник
comment
Пожалуйста, отредактируйте свой вопрос, включив в него минимальный воспроизводимый пример, включая ввод и вывод. Вы определенно не хотите кодировать в процентах все входные данные, вам нужно только снова кодировать те, которые печатаются в HTML.   -  person CodeCaster    schedule 20.11.2016
comment
Спасибо, CodeCaster. Я обновил вопрос, как было предложено.   -  person Alok    schedule 21.11.2016
comment
@Alok вы имеете в виду, что приложение записывает необработанные входные строки непосредственно в ответ, тем самым обходя все проверки безопасности и защиты ASP.NET? Тогда да, вам нужно исправить каждую строчку ошибочного кода. И добавьте проверку всех текстовых полей, чтобы они не допускали недопустимый ввод.   -  person Panagiotis Kanavos    schedule 21.11.2016
comment
Да, если ты собираешься Response.Write(TextBox1.Text), тебе будет плохо. Этот шаблон часто встречается в вашем коде?   -  person CodeCaster    schedule 21.11.2016
comment
Либо ваша страница, либо StringOps должны проверить ввод и отклонить недопустимые данные. Лучшим местом, конечно же, будет сама страница. Что делает StringOps?   -  person Panagiotis Kanavos    schedule 21.11.2016
comment
Да, это в основном написано только так. Вот почему ищу какой-то интерфейс, который будет выполнять кодирование, прежде чем отправлять его обратно в браузер в качестве ответа.   -  person Alok    schedule 21.11.2016
comment
@PanagiotisKanavos: StringOps - это всего лишь фиктивный класс, который я создал для размещения здесь фрагмента кода. У нас есть несколько классов, которые принимают входные данные из пользовательского интерфейса, выполняют некоторые операции и отправляют их обратно в пользовательский интерфейс.   -  person Alok    schedule 21.11.2016
comment
@Alok, вы обходите любой такой интерфейс, используя Response.Write. Это отправляет клиенту необработанный текст. Почему ты вообще это делаешь? Это что-то вроде REST-сервиса? В любом случае ошибка в том, что вы не проверяете свой ввод. Кодирование только скроет ошибку от инструмента проверки. Это не предотвратит, например, SQL-инъекцию, если клиент введет x'; drop table users; --   -  person Panagiotis Kanavos    schedule 21.11.2016
comment
Алок, я чувствую, что даже если вы найдете способ предотвратить использование XSS в одном месте, Veracode может не распознать этот подход и по-прежнему жаловаться, когда не видит используемый HtmlEncode. Хотя это просто ощущение.   -  person GreatJobBob    schedule 22.11.2016
comment
Если вы HTMLEncode аргумент для Response.Write, отметит ли Veracode это?   -  person jdigital    schedule 27.11.2016
comment
как вы указали, вы, вероятно, сможете справиться с этим, определив и добавив пользовательский HttpModule в свой web.config .. что это за приложение и это страницы? (веб-форма - aspx?). кроме того, есть ли шаблон подчеркивания, который можно определить для этих запросов ... например, в url, fileExt или в этом отношении ...   -  person Brett Caswell    schedule 27.11.2016
comment
вы можете использовать https://msdn.microsoft.com/en-us/library/system.web.httpresponse.filter.aspx для ваших целей здесь ... в конце концов, вы хотите перехватить OutputStream объекта HttpResponse .. Вопрос, связанный с SO: stackoverflow.com/questions/2282376/   -  person Brett Caswell    schedule 27.11.2016


Ответы (2)


Вы можете сделать это с помощью Custom HttpModule, который условно назначается HttpResponse.Filter для перехвата и обработки HttpResponse.Write использования.


Пример модуля

в этом примере используется значение Content-Type request.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>
person Brett Caswell    schedule 27.11.2016
comment
Кажется, это отвечает на вопрос, но держу пари, что Veracode все равно будет жаловаться (?) - person jdigital; 27.11.2016
comment
@jdigital потенциально, но похоже, что этот фреймворк / компонент / инструмент veracode сканирует приложение, делает запросы и анализирует ответ .. - person Brett Caswell; 27.11.2016
comment
что напоминает мне ... byte[] buffer, передаваемый на запись, тоже может быть обработан условно ... и, вероятно, вызов Write будет сделан несколько раз. потребуется лучший образец ответа OP, чтобы отразить это соображение. - person Brett Caswell; 27.11.2016

Послушайте, у меня также есть старый сайт в asp.net 1.0 или 2.0. Мы изменили его фреймворк на 4.0.

Итак, я предлагаю изменить его структуру и запустить дымовой тест, и, возможно, возникнут некоторые проблемы, которые будут решены, как ожидалось, а затем перейдут к первоочередной задаче обработки таких вещей, как Response.Write. Поскольку ASP.net теперь является открытым исходным кодом, получите этот код и внесите минимальные изменения в основные функции и добейтесь своей цели, постарайтесь максимально использовать частичные функции или что-то подобное, чтобы получить обновление без потери ваших изменений.

person Mohtisham Zubair    schedule 21.11.2016