简体   繁体   English

如何在所有ASP.NET AJAX HTTPS响应中安全地添加随机填充?

[英]How do I securely add a random padding to all ASP.NET AJAX HTTPS responses?

Apparently, it is possible to leak data in an SSL connection based on the size of the HTTPS request and response. 显然, 可以根据 HTTPS请求和响应的大小在SSL连接中泄漏数据

Considering the complexity of the ASP.NET pipeline, how do I securely add a random amount of data that rounds each size up to the nearest 500K? 考虑到ASP.NET管道的复杂性,如何安全地添加随机数量的数据,将每个大小舍入到最接近的500K?

The security constraints (as I'm aware of now) are 安全限制(我现在已经知道)是

  • Don't leak timing information, and always take the same amount of time when generating the extra data 不要泄漏计时信息,并且在生成额外数据时总是花费相同的时间

  • Always round up to the next 500K value 始终向下舍入到下一个500K值

  • The data used as padding doesn't have to be random, our goal is to change the size of the HTTPS response 用作填充的数据不必是随机的,我们的目标是更改HTTPS响应的大小

I'll post the related javascript question (HTTP POST) in a separate question as a courtesy to the PHP users who may not be looking at ASP implementations ;) 我将在一个单独的问题中发布相关的javascript问题 (HTTP POST)作为对可能没有查看ASP实现的PHP用户的礼貌;)

Well you can create a filter to modify response before sending it to client. 那么你可以创建一个过滤器来修改响应,然后再将其发送给客户端。 All you have to do is create a IHttpModule and intercept ASP.NET request pipeline. 您所要做的就是创建一个IHttpModule并拦截ASP.NET请求管道。 You can set Filter Stream, which will buffer your response, and at the end, ASP.NET pipeline will call "Close" method, that time you can modify buffer and send back to client. 您可以设置Filter Stream,它将缓冲您的响应,最后,ASP.NET管道将调用“Close”方法,那时您可以修改缓冲区并发送回客户端。

To improve performance, you can also intercept Write method and write better logic instead of buffering whole response. 为了提高性能,您还可以截取Write方法并编写更好的逻辑,而不是缓冲整个响应。 But I will leave it on you. 但是我会留在你身上。

First configure your web.config as, 首先将web.config配置为,

<system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
        <add name="RandomPaddingModule"
             type="Namespace.RandomPaddingModule, AssemblyName"/>
    </modules>
</system.webServer>

And add following code 并添加以下代码

public class RandomPaddingModule : IHttpModule{

    public void Dispose()
    {
    }

    public void Init(HttpApplication context)
    {
        // Apply filter immediately
        context.BeginRequest += (s, e) =>
        {
            context.Response.Filter = 
               new RanndomPaddingStream(context.Response.Filter,
                   context.Context);

        };
    }

}


public class AtomPreCompilerStream : ResponseFilterStream
{

    private HttpContext context;

    public RanndomPaddingStream(Stream s, HttpContext c)
        : base(s)
    {
        this.context = c;
    }

    // process buffer before sending it to client...
    protected override byte[] ProcessBuffer(byte[] p)
    {

         if(string.Equals(
               context.Response.ContentType,
               "application/json", 
               StringComparison.OrdinalIgnoreCase)){
             // do some padding....
         }

         return p;
    }
}

public class ResponseFilterStream: Stream
{
    /// <summary>
    /// The original stream
    /// </summary>
    Stream _stream;


    /// <summary>
    /// Stream that original content is read into
    /// and then passed to TransformStream function
    /// </summary>
    MemoryStream _cacheStream = new MemoryStream(5000);

    public byte[] Buffer
    {
        get
        {
            return _cacheStream.ToArray();
        }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="responseStream"></param>
    public AtomPreCompilerFilterStream(Stream responseStream)
    {
        _stream = responseStream;
    }


    /// <summary>
    /// 
    /// </summary>
    public override bool CanRead
    {
        get { return true; }
    }

    public override bool CanSeek
    {
        get { return true; }
    }
    /// <summary>
    /// 
    /// </summary>
    public override bool CanWrite
    {
        get { return true; }
    }

    /// <summary>
    /// 
    /// </summary>
    public override long Length
    {
        get { return 0; }
    }

    /// <summary>
    /// 
    /// </summary>
    public override long Position
    {
        get { return _cacheStream .Position; }
        set { _cacheStream .Position = value; }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="offset"></param>
    /// <param name="direction"></param>
    /// <returns></returns>
    public override long Seek(long offset, System.IO.SeekOrigin direction)
    {
        return _cacheStream.Seek(offset, direction);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="length"></param>
    public override void SetLength(long length)
    {
        _cacheStream .SetLength(length);
    }

    /// <summary>
    /// 
    /// </summary>
    public override void Close()
    {
        byte[] data = ProcessBuffer(_cacheStream.ToArray());
        _stream.Write(data, 0, data.Length);
        _stream.Close();
    }

    protected virtual byte[] ProcessBuffer(byte[] p)
    {
        return p;
    }

    /// <summary>
    /// Override flush by writing out the cached stream data
    /// </summary>
    public override void Flush()
    {

        // default flush behavior
        //_stream.Flush();
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="buffer"></param>
    /// <param name="offset"></param>
    /// <param name="count"></param>
    /// <returns></returns>
    public override int Read(byte[] buffer, int offset, int count)
    {
        return _cacheStream.Read(buffer, offset, count);
    }


    /// <summary>
    /// Overriden to capture output written by ASP.NET and captured
    /// into a cached stream that is written out later when Flush()
    /// is called.
    /// </summary>
    /// <param name="buffer"></param>
    /// <param name="offset"></param>
    /// <param name="count"></param>
    public override void Write(byte[] buffer, int offset, int count)
    {
        _cacheStream.Write(buffer, offset, count);
        //_stream.Write(buffer, offset, count);

    }

}

Having read the linked articles, I first want to say that best security would probably be clientside; 阅读链接文章后,我首先要说的是最好的安全性可能是客户端; a trusted, secure proxy -- this type of analysis relies upon intimate knowledge of the application, if the attacker can't tell what website your visiting, it can't analyze the responses. 一个值得信赖的安全代理 - 这种类型的分析依赖于对应用程序的深入了解,如果攻击者无法分辨您访问的网站,则无法分析响应。

That said, there are things you can do to make YOUR site less vulnerable. 也就是说,有些事情可以让您的网站不那么容易受到攻击。 But its going to be more complex than just simple padding. 但它会比简单的填充更复杂。 One of the examples given is picking a doctor. 其中一个例子是选择医生。 The list of available doctors is available to all visitors. 所有访客都可以获得可用医生名单。 If you have an auto complete its not hard at all to reduce the number of potential doctors down significantly given that you can watch the traffic. 如果你有一个汽车完成它根本不是很难减少潜在医生的数量,因为你可以观察流量。 An extreme example would be 500 doctors, only one with a name starting with Z: Dr Zhivago. 一个极端的例子是500名医生,只有一名名字以Z开头:Zhivago博士。 Thus a 1 letter send that returns one doctor is probably him. 因此,一封寄回一位医生的信件可能是他。 Padding the send and receive data won't be enouh to hide this if it is based on a simple rounding up to the nearest 500 bytes. 如果基于简单的舍入到最接近的500字节,则填充发送和接收数据将不会隐藏它。 One send and receive that then moves on to the next action on the page is still going to be him. 一个发送和接收,然后继续到页面上的下一个操作仍然是他。 In this type of situation you can do several things -- first is always return MORE than one possibility, even when there is only one, reduce it to just one on the client. 在这种情况下,你可以做几件事 - 首先总是返回多种可能性,即使只有一种,在客户端只减少一种。 Secondly pad the number of REQUESTS, not just the data in the request. 其次填充REQUESTS的数量,而不仅仅是请求中的数据。

Back to your question, compression makes padding something of a problem as the compressed size leaks. 回到你的问题,压缩使填充成为一个问题,因为压缩的大小泄漏。 Pad as much as you can with valid data that is filtered out on the client, this will make any attempt to analyze it harder. 使用在客户端上过滤掉的有效数据尽可能多地填充,这将使任何尝试更难分析它。 Be sure that you don't leak padding time when doing your padding. 在做填充时,请确保不会泄漏填充时间。

Finally -- this type of attack would have to be application and possibly user specific. 最后 - 这种类型的攻击必须是应用程序,可能是用户特定的。 Does anyone really care that much about your traffic? 有没有人真正关心你的流量?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何为ASP.NET AJAX计时器控件设置随机间隔? - How do I set a random Interval for ASP.NET AJAX Timer control? 如何在ASP.Net中将除单个URL以外的所有URL重定向到https? - How do I redirect all but a single url to https in ASP.Net? 如何将HTTPS添加到asp.net网站以进行帐户登录? - How do I add HTTPS to my asp.net website for account login? 如何安全地读取asp.net根配置文件夹? - How do I securely read the asp.net root configuration folder? 如何安全地获取正在运行的ASP.NET站点的域名 - How do I securely get the domain name of the running ASP.NET site 如何更改将由ASP.NET中的数据表处理的Ajax响应? - How to alter ajax responses that will be handled by DataTables in ASP.NET? 如何在ASP.NET AJAX ValidatorCalloutExtender创建的表上禁用填充? - How can I disable padding on table created by ASP.NET AJAX ValidatorCalloutExtender? 如何将ASP.net ajax AccordionPane绑定到XMLDatasource? - How do I bind an ASP.net ajax AccordionPane to an XMLDatasource? 我如何读取asp.net中的所有X标头 - How do I read all X Headers in asp.net ASP.NET如何将javascript函数添加到控件? - ASP.NET How do I add javascript function to a control?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM