Search code examples
c#readlinestreamreaderddos

How to limit the number of characters read by StreamReader.ReadLine() in .NET?


I am writing a web server application in C# and using StreamReader class to read from an underlying NetworkStream:

 NetworkStream ns = new NetworkStream(clientSocket);
 StreamReader sr = new StreamReader(ns);
 String request = sr.ReadLine();

This code is prone to DoS attacks because if the attacker never disconnects we will never finish reading the line. Is there any way to limit the number of characters read by StreamReader.ReadLine() in .NET?


Solution

  • You would have to use the Read(char[], int, int) overload (which does limit the length) and do your own end-of-line detection; shouldn't be too tricky.

    For a slightly lazy version (that uses the single-characted reading version):

    static IEnumerable<string> ReadLines(string path, int maxLineLength)
    {
        StringBuilder currentLine = new StringBuilder(maxLineLength);
        using (var reader = File.OpenText(path))
        {
            int i;
            while((i = reader.Read()) > 0) {
                char c = (char) i;
                if(c == '\r' || c == '\n') {
                    yield return currentLine.ToString();
                    currentLine.Length = 0;
                    continue;
                }
                currentLine.Append((char)c);
                if (currentLine.Length > maxLineLength)
                {
                    throw new InvalidOperationException("Max length exceeded");
                }
            }
            if (currentLine.Length > 0)
            {
                yield return currentLine.ToString();
            }                
        }
    }