MaxReceivedMessageSize, MaxBufferSize, and proxy generation

To limit DoS exposure, we have a knob on all of our transports to control the size of Messages received on the wire. This way, we will only allocate a bounded amount of memory for each message. This setting is binding.MaxReceivedMessageSize in imperative code (or <binding maxReceivedMessageSize="654321"> in config). If an incoming Message is larger than MaxReceivedMessageSize, we will drop the Message (and fault the transport channel for session-ful channels).

Many of our transports/bindings also have a “MaxBufferSize” knob. For buffered transports, this value is always equal to MaxReceivedMessageSize (and the system Asserts this fact). However, for Streamed bindings (TransferMode == TransferMode.Streamed), we only need to buffer the SOAP Headers in order to generate a Message, and we can have the Body stream in on-demand. In this case, MaxBufferSize <= MaxReceivedMessageSize, and MaxReceivedMessageSize will bound the overall message, while MaxBufferSize bounds the Headers size.

One thing to note about these settings is that they are local behavioral settings. That is, they are not transmitted in Metadata. So if you generate a proxy to a service with a MaxReceivedMessageSize = 2GB, the proxy will have a default value (64K) for MaxReceivedMessageSize. This leaves control of the appropriate MaxReceivedMessageSize in the hands of the administrator to decide, and (hopefully) helps with our out-of-the-box security story.

7 thoughts on “MaxReceivedMessageSize, MaxBufferSize, and proxy generation

  1. Pingback: mattonsoftware.com : .NET Resources

  2. Ali Pasha

    One of the issues that we’ve found is that this doesn’t work for DataSets as they are usually bigger than the default MessageSize. This means that the user has to go in, find the setting, and manually change it whenever they are consuming a DataSet.

    Is there any nice workaround for this issue?

    Thanks

    Reply
  3. Rajesh

    Hi Kenny,

    I am encountering a different issue. I have my WCF running on a windows service mode and one of the method calls it actually returns about 4000 rows from the database.

    Now on the client side when I access this method it gives me the error message as below:

    An error occurred while receiving the HTTP response to http://192.168.1.71:2000/XYZService . This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details.

    Below is how my service and client configurator looks. I have tried transfermode as both streamed and buffered, but no luck.

    Could you please let me know how could I overcome this issue.

    service:

    client:

    Reply
  4. rick watson

    Good morning, I need to generate my clients (currently using the dynamicproxy) code as presented on the wcf.netfx3.com site. How can I specify the maxreceivedmessagesize. thank you for any assistance

    Reply
  5. Kenny

    If you are generating config for your client, then you can specify maxReceivedMessageSize in the config. Rajesh, I would recommending isolating a couple things — try localhost first, make sure that’s good, then go offbox. It may be that you need to use netmon to track down what’s going wrong here.

    Reply
  6. Rune

    What Binding?

    FTransportBinding = new NetTcpBinding();
    FTransportBinding.MaxReceivedMessageSize = 2048 * 1024; //won’t compile

    There’s no such property there.

    MSDN docs mention BindingElement or some such thing, but of course leaves few clues as to where I can get at those parts.

    I’m getting very frustrated with WCF. I come from a Borland Delphi background, and having full source to the library is the key to successfull development. Black boxes are so 80s.

    Reply
  7. Kenny

    NetTcpBinding has that property:
    public long MaxReceivedMessageSize
    {
    get { return transport.MaxReceivedMessageSize; }
    set { transport.MaxReceivedMessageSize = value; }
    }

    BTW, you can use Reflector to take a look at the internals very easily.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *