Wednesday 22 August 2012

Denial of service (DoS) attacks on your Wcf services


Denial of service (DoS) attacks on your Wcf services


What can you do to prevent denial of service (DoS) attacks on your Wcf services?  A DoS attack occurs when a flood of client requests come into a service and prevent requests from being made or slow down processing.  At the same time, you need to be careful not to requests and activity.

Throttling

Throttling is one mechanism that can be used to help minimize the load from a DoS attack.  Throttling allows you to "smooth" out the load on the server.

Wcf handles throttling through the ServiceThrottlingBehavior class.  This represents a behavior that can be applied to a service.  Behaviors can be applied programmatically:

ServiceHost host = new ServiceHost(
    typeof(MyContract),
host.AddServiceEndpoint(
    "IMyContract",
    new WSHttpBinding(),
    "");
System.ServiceModel.Description.ServiceThrottlingBehavior throttlingBehavior =
    new System.ServiceModel.Description.ServiceThrottlingBehavior();
throttlingBehavior.MaxConcurrentCalls = 16;
throttlingBehavior.MaxConcurrentInstances = Int32.MaxValue;
throttlingBehavior.MaxConcurrentSessions = 10;
host.Description.Behaviors.Add(throttlingBehavior);
host.Open();

or through the app.config:

<system.serviceModel>
    <services>
        <service
            name="IMyContract"
            behaviorConfiguration="myContract">
            <host>
                <baseAddresses>
                    <add baseAddress="http://localhost:8080/MyContract"/>
                </baseAddresses>
            </host>
            <endpoint
                name="wsHttp"
                address=""
                binding="wsHttpBinding"
                contract="IMyContract">
            </endpoint>
        </service>
    </services>
    <behaviors>
        <serviceBehaviors>
            <behavior name="myContract">
                <serviceMetadata httpGetEnabled="True" />
                <serviceThrottling
                    maxConcurrentCalls="16"
                    maxConcurrentInstances="2147483647"
                    maxConcurrentSessions="10"/>
            </behavior>
        </serviceBehaviors>
    </behaviors>
</system.serviceModel>


There are 3 properties supported on the ServiceThrottlingBehavior:
  1. MaxConcurrentCalls (default = 16) [Per-message] The maximum number of messages that can actively be processed.  Each client channel can have one pending message that does not count against this total until the service begins to process it.  Increase this value if you want your service to be able to process a larger message load.
  2. MaxConcurrentInstances (default = Int32.Max)  The maximum number of InstanceContext objects in a service that can execute at one time.
    • What this setting translates into depends on the InstanceContextMode that is set on the ServiceBehaviorAttribute on the service.  If this is set to "PerSession", then this would represent the maximum number of sessions.  If this is set to "PerCall", then this is the maximum number of concurrent calls.  If this is set to "Single", then this value doesn’t really mean anything anymore.
    • When a message comes into the service and the maximum number of InstanceContext objects already exists, then the message goes into a wait pattern until an existing InstanceContext is closed.  This could cause a client to receive a timeout if no connection could be created in the allotted amount of time.
  3. MaxConcurrentSessions (default = 10) [Per-channel] The maximum number of sessions that a service can accept at one time.  This setting only affects "session" enabled channels, so a channel like BasicHttpBinding will not be affected.  Once this threshold is reached, no channels will not be accepted to the service.  Each listener object can have one pending channel session that does not count against this total until the service beings to process it.  Increase this value if you want to allow more than 10 concurrent sessions to be connected at any given time.
    • If you get exceptions like this, you may need to increase this value:
"The open operation did not complete within the allotted timeout of 00:00:59.9989999. The time allotted to this operation may have been a portion of a longer timeout."

"The socket transfer timed out after 00:00:59.9979998. You have exceeded the timeout set on your binding. The time allotted to this operation may have been a portion of a longer timeout."
You could set all the these values to Int32.Max.  This is probably a good think when you really want to perform some load testing of the server. (This is how I discovered the usefulness of these settings)  However it is important to understand what consequences there are to doing this.

Recommendations:
If your InstanceContext is set to "PerCall" you should set maxConcurrentSessions and maxConcurrentCalls to the same value since each call is its own session.  You should target this value to be at least 25-30.  However you shouldn’t need to go higher than 64.
If your InstanceContext is set to "PerSession" you should set maxConcurrentCalls to be at least 25-30.  Your maxConcurrentSessions should be the number of users you want to have concurrently connected.
If your InstanceContext is set to "Single" you should use the same settings as "PerSession", but the maxConcurrentSessions will only apply if session support is active (this is set with the SessionMode attribute on the ServiceContractAttribute).

Quotas
Another potential area that is vulnerable to a DoS attack is where the client may force the server to allocate a significant amount of memory over what should be used.   To help prevent this you can use Quotas.  When a quota is exceeded a QuotaExceededException is thrown.  Without Quotas a malicious message could attempt to access all available memory can create an OutOfMemoryException, or access all available stacks to cause a StackOverflowException.  The best part of the QuotaExceededException is that the message causing it can just be discarded and the service can keep on running.  Without quotas the resulting exceptions could cause the service to terminate.
The most useful quota to work with to mitigate DoS attacks is the maxRecievedMessageSize on the binding itself.  This setting restricts the maximum messages size so that a client can’t send messages that are too large and flood the system.  The default value is 65536 bytes.
<bindings>
    <netTcpBinding>
        <binding name="netTcp"
            maxReceivedMessageSize="2147483647"
            maxConnections="2147483647">
            <readerQuotas
                maxDepth="64"
                maxStringContentLength="2147483647"
                maxArrayLength="2147483647"
                maxBytesPerRead="4096"
                maxNameTableCharCount="16384"/>
        </binding>
    </netTcpBinding>
</bindings>


Other quotas exist on the ReaderQuotas property that can be used to restrict message complexity.  This can help mitigate excessive use of endpoint processing resources like CPU and memory. These are:
  1. MaxDepth (default = 32) The maximum nested node depth.
  2. MaxStringContentLength (default = 8192)  The maximum string length allowed by the reader.  You may need to increase this value if you anticipate potentially large messages.
  3. MaxArrayLength (default = 16384)  The maximum allowed array length.  How many items can be in a single array in the message.
  4. MaxBytesPerRead (default = 4096) The maximum allowed bytes returned for each read.  This is the number of bytes consumed by a single call from the reader to Read().  In practice this is used to limit the size of start tags, since a start tag must be completely buffered for the message to be processed.  This can be a common attack area.  It is recommended to keep this value at its default.
  5. MaxNameTableCharCount (default = 16384) The maximum number of characters in a table name.
Some bindings such as Net
TcpBinding offer a maxConnections property.  This setting on the client indicates the maximum number of connections to be pooled for subsequent reuse.  On the server, this setting is the maximum number of connections allowed to be pending dispatch.  The default is 10.


Happy Programming ! !
If you have any query mail me to Sujeet.bhujbal@gmail.com     
Regards
Sujeet Bhujbal
-----------------------------------------------------------
---------------------------------------------------------------

Thursday 2 August 2012

DataContractSerializer in WCF



What is Serialization?

Let’s start with the basics.  Serialization has been a key part of .Net since version 1.  It is basically the process of converting an object instance into a portable and transferable format.  The objects can be serialized into all sorts of formats.  Serializing to Xml is most often used for its interoperability.  Serializing to binary is useful when you want to send the object from one .Net application to another.  .Net even supports the interfaces and base classes to build your own serializes. There are libraries out there to serialize to comma delimited strings, JSON, etc.
Deserialization is basically the reverse of serialization.  Its the process of taking some data (Xml, binary, etc) and converting it back into an object.

What is the XmlSerialzer?

For those that may not be familiar with System.Xml.Serialization.XmlSerializer let’s go over it briefly.  This is the xml serializer that has been around since .Net version one.  To serialize or deserialize an object, you basically just need to create an instance of the XmlSerializer for the type you want to work with, then just call Serialize() or Deserialize().  It works with streams, so you could serialize to any stream such as an MemoryStream, FileStream, etc.
// Create serializer for the type
System.Xml.Serialization.XmlSerializer xmlSerializer =
    new System.Xml.Serialization.XmlSerializer(typeof(MyType)); 
 
// Serialize from an object to a stream
xmlSerializer.Serialize(stream, myInstanceOfMyType); 
 
// Deserialize from a stream to an object
myInstanceOfMyType = (MyType)xmlSerializer.Deserialize(stream);

What is the DataContractSerializer?

The System.Runtime.Serialization.DataContractSerializer is new in .Net 3.0 and was designed for contract-first development and speed.  Specifically it was brought in to be used by Wcf, but can be used for general serialization as well. Using the DataContractSerializer isn’t that much different than using the XmlSerializer.  There are a few more options, but the only real key difference is that you use a WriteObject() method to serialize instead of a Serialize() method and a ReadObject() method to deserialize instead of a Deserialize() method.  It works with the same types of streams, so you can write to memory, files, etc.
DataContractSerializer dataContractSerializer =
    new DataContractSerializer(typeof(MyType)); 
 
// Serialize from an object to a stream
dataContractSerializer.WriteObject(stream, myInstanceOfMyType); 
 
// Deserialize from a stream to an object
myInstanceOfMyType = (MyType)dataContractSerializer.ReadObject(stream);







A The XmlSerializer has been in .Net since version 1.0 and has served us well for everything from Remoting, Web Services, serializing to a file, etc. However in .Net 3.0 the DataContractSerializer came along.  And all of a sudden a lot of guidance suggests that we should use it over the old tried and true XmlSerializer. Wcf even uses this as the default mechanism for serialization.  The question is, “Is it really better?”.  The verdict is yes, and no.  Like most things it depends on your implementation and what you need.  For Wcf, you should prefer to use the DataContractSerializer.  If you need full control over how the xml looks though, you should go back to the XmlSerializer.
Lets look at the both of these in detail and leave it up to you to decide which is best for your implementation.  Here are a few of the advantages and disadvantages of each of them:


Advantages:
1. Opt-out rather than opt-in properties to serialize. This mean you don’t have to specify each and every property to serialize, only those you don’t wan to serialize2. Full control over how a property is serialized including it it should be a node or an attribute
3. Supports more of the XSD standard
Disadvantages:
1. Can only serialize properties
2. Properties must be public
3. Properties must have a get and a set which can result in some awkward design
4. Supports a narrower set of types
5. Cannot understand the DataContractAttribute and will not serialize it unless there is a SerializableAttribute too
Advantages:
1. Opt-in rather than opt-out properties to serialize. This mean you specify what you want serialize
2. Because it is opt in you can serialize not only properties, but also fields.  You can even serialize non-public members such as private or protected members. And you dont need a set on a property either (however without a setter you can serialize, but not deserialize)
3. Is about 10% faster than XmlSerializer to serialize the data because since you don’t have full control over how it is serialize, there is a lot that can be done to optimize the serialization/deserialization process.
4. Can understand the SerializableAttribute and know that it needs to be serialized
5. More options and control over KnownTypes
Disadvantages:
1. No control over how the object is serialized outside of setting the name and the order



Below example class setup to use the DatContractSerializer.  Notice that I am explicitly setting the DataMemberAttribute on the properties I want to serialize, but not on the others.
[DataContract]
public class Individual
{
    private string m_FirstName;
    private string m_LastName;
    private int m_SocialSecurityNumber; 
 
    [DataMember]
    public string FirstName
    {
        get { return m_FirstName; }
        set { m_FirstName = value; }
    } 
 
    [DataMember]
    public string LastName
    {
        get { return m_LastName; }
        set { m_LastName = value; }
    } 
 
    public int SocialSecurityNumber
    {
        get { return m_SocialSecurityNumber; }
        set { m_SocialSecurityNumber = value; }
    } 
 
    public Individual()
    {
    }
    public Individual(string firstName, string lastName)
    {
        m_FirstName = firstName;
        m_LastName = lastName;
    }
}

One other important thing to talk about with the DataContractSerializer are the ServiceKnownTypeAttribute and KnownTypeAttribute attributes.  These are similar to the XmlIncludeAttribute used by the XmlSerializer.  When used in Wcf, these identify what types should be represented in the WSDL that is generated.
The KnownTypeAttribute specifies types that should be recognized by the DataContractSerializer when serializing and deserializing a type.  It is applied to a class and basically specifies what other types are used in the class.  You don’t need to specify known .Net types, but any custom classes should be added here.  This attribute can be used multiple times to identify multiple types.
[DataContract]
[KnownType(typeof(MyOtherType))]
public class MyType
{
    [DataMember]
    public MyOtherType TheOtherType;
} 
 
[DataContract]
public class MyOtherType
{
    [DataMember]
    public string MyValue;
}
The ServiceKnownTypeAttribute specifies known types to be used by a service when serializing or deserializing.  It is applied to a ServiceContract or to an OperationContract and specifies what types are used in the methods.  Again (like the KnownTypeAttribute), you don’t need to specify known .Net types and this attribute can be used multiple times to identify multiple types.
[ServiceContract]
[ServiceKnownType(typeof(MyType))]
[ServiceKnownType(typeof(MyOtherType))]
public interface MyService
{
    [OperationContract]
    [ServiceKnownType(typeof(YetAnotherType))]
    void MyMethod();
}

When to use which serializer?

For Wcf, you should prefer to use the DataContractSerializer.  If you need full control over how the xml looks though, you should go back to the XmlSerializer.   If you are doing general serialization, it is up to you, but I would weigh out the advantages and disadvantages.  I would still prefer the DataContractSerializer for the same reasons I prefer it for Wcf.  I do not recommend using the NetDataContractSerializer unless you have to.  You can lose too much interoperability and its not as descriptive.
If you need some custom xml serializer, by all means go ahead and implement it.  Wcf supports any serializer you can throw at it.  Just be careful not to “reinvent the wheel”.  The XmlSerializer is very configurable and may suit your needs. If that doesn’t work, then ISerializable gives you full control.