Search code examples
javasecurityiobufferedreader

Safe implementation of BufferdReader


I want to use a BufferedReader to read a file uploaded to my server.

The file would by written as a CSV file, but I can't assume this, so I code some test where the file is an image or a binary file (supposing the client has sent me the wrong file or an attacker is trying to break my service), or even worse, the file is a valid CSV file but has a line of 100MB.

My application can deal with this problem, but it has to read the first line of the file:

...
String firstLine = bufferedReader.readLine();
//Perform some validations and reject the file if it's not a CSV file
...

But, when I code some tests, I've found a potential risk: BufferedReader doesn't perform any control over the amount of bytes it reads until it found a return line, so it can ended up throwing an OutOfMemoryError.

This is my test:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import org.junit.Test;

public class BufferedReaderTest {

    @Test(expected=OutOfMemoryError.class)
    public void testReadFileWithoutReturnLineCharacter() throws IOException {
        BufferedReader bf = new BufferedReader(getInfiniteReader());

        bf.readLine();

        bf.close();
    }

    private Reader getInfiniteReader() {
        return new Reader(){

            @Override
            public int read(char[] cbuf, int off, int len) throws IOException {
                return 'A';
            }

            @Override
            public void close() throws IOException {

            }
        };
    }
}

I've been looking up some safe BufferedReader implementation on the internet, but I can't find anything. The only class I've found was BoundedInputStream from apache IO, that limits the amount of bytes read by an input stream.

I need an implementation of BufferedReader that knows how to limit the number of bytes/characters read in each line.

Something like this:

  • The app calls 'readLine()'
  • The BufferedReader reads bytes until it found a return line character or it reaches the maximum amount of bytes allowed
  • If it has found a return line character, then reset the bytes read (so it could read the next line) and return the content
  • If it has reached the maximum amount of bytes allowed, it throws an exception

Does anybody knows about an implementation of BufferedReader that has this behaviour?


Solution

  • Thank you @fge for the answer. I ended up implementing a safe Readerthat can deal with files with too long lines (or without lines at all).

    If anybody wants to see the code, the project (very small project even with many tests) is available here:

    https://github.com/jfcorugedo/security-io