WCF (Windows Communication Foundation)
.NET Framework 4.7.1
WCF (Windows Communication Foundation) is a framework for building service-oriented applications. It is used in web services as well as inter process communication.
A weakness in this framework might expose applications that use it to DOS attacks.
WCF framework takes care of de-serializing the input to the application and of serializing the output that it returns. It supports both XML and JSON formats.
If a highly nested object is being returned by the application, a StackOverflowException is being throwed and the hosting process is terminated immediately (see our blog post).
If an attacker can build a highly nested object in the system and then use the API to get this object, s/he can remotely crashes the application.
For example, if the API provides a way to build a tree structure by adding nodes iteratively and it also provides a way to retrieve the entire tree, an attacker can build a deep tree and then crash the application by requesting the entire tree.
Applications that contain such a pattern, will be vulnerable to a DOS attack due to poor implementation of the serializer that is used by the framework.
I reported this issue to Microsoft on July 30 2018. A case was opened, but Microsoft closed it as “by design”.
I was surprised by this response. How can you design a framework that crash the process by design when handling a highly nested object? I would expect it to return an appropriate error message.
Here is an example of WCF service that crashes the application when being called with big depth (~2000):
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
 
namespace TestService
{
    [DataContract]
    public class TreeNode
    {
        [DataMember]
        public TreeNode[] Suns { get; set; }
    }
 
 
    [ServiceContract]
    public interface ITreeService
    {
        [OperationContract]
        TreeNode GetTree(int depth);
    }
 
    [ServiceBehavior]
    public class TreeService : ITreeService
    {
        [WebGet(UriTemplate = "GetTree?depth={depth}")]
        public TreeNode GetTree(int depth)
        {
            TreeNode root = new TreeNode();
            TreeNode iNode = root;
            for (int i = 0; i < depth; i++)
            {
                iNode.Suns = new TreeNode[] { new TreeNode() };
                iNode = iNode.Suns[0];
            }
 
            return root;
        }
    }
}