We tracked the following data from "param" Parameter:
GET /grizzly/readline?param=testdata
...which was accessed within the following code:
com.contrastsecurity.bufferedreader.readline.UnsafeReadlineHandler#service(), line 26
...and ended up being consumed (through a reader object) by a method which reads until a newline is encountered:
java.io.BufferedReader@61a627ac
What's the risk?
The application calls the dangerous readLine() method on a stream of data that is controlled by the user. This method reads data until a newline character is encountered. A user can supply a never-ending stream of bytes and never provide a newline, and consume all of the available system memory, eventually taking down the container.
Recommendation
The most obvious way to prevent an unchecked read is to put a control around how many bytes or characters can be read from a given stream before giving up.
Here's an example of a "readLine()" replacement that implements such a control. This was adapted from the ESAPI library (BSD license):
public String safeReadLine(InputStream in, int max) {
if (max <= 0) {
throw new IllegalArgumentException( "Invalid readline. Must read a positive number of bytes from the stream");
}
StringBuilder sb = new StringBuilder();
int count = 0;
int c;
try {
while (true) {
c = in.read();
if ( c == -1 ) {
if (sb.length() == 0) {
return null;
}
break;
}
if (c == '\n' || c == '\r') {
break;
}
count++;
if (count > max) {
throw new IllegalArgumentException("Invalid readLine. Read more than maximum characters allowed (" + max + ")");
}
sb.append((char) c);
}
return sb.toString();
} catch (IOException e) {
throw new IllegalArgumentException( "Problem reading from input stream", e);
}
}
Vulnerability ID: GM10-HEUV-ZSBO-ZC12
Application Name: JavaThree
Application Code: JAVA3
Vulnerability Link: http://localhost:19080/Contrast/static/ng/index.html#/7c6cfec5-a187-4d5e-984a-d11d96d2ef63/applications/0ef9bd52-f372-4751-a215-cf25f9945c6a/vulns/GM10-HEUV-ZSBO-ZC12
What Happened?
We tracked the following data from "param" Parameter:
GET /grizzly/readline?param=testdata
...which was accessed within the following code:
com.contrastsecurity.bufferedreader.readline.UnsafeReadlineHandler#service(), line 26
...and ended up being consumed (through a reader object) by a method which reads until a newline is encountered:
java.io.BufferedReader@61a627ac
What's the risk?
The application calls the dangerous readLine() method on a stream of data that is controlled by the user. This method reads data until a newline character is encountered. A user can supply a never-ending stream of bytes and never provide a newline, and consume all of the available system memory, eventually taking down the container.
Recommendation
The most obvious way to prevent an unchecked read is to put a control around how many bytes or characters can be read from a given stream before giving up.
Here's an example of a "readLine()" replacement that implements such a control. This was adapted from the ESAPI library (BSD license): public String safeReadLine(InputStream in, int max) { if (max <= 0) { throw new IllegalArgumentException( "Invalid readline. Must read a positive number of bytes from the stream"); } StringBuilder sb = new StringBuilder(); int count = 0; int c; try { while (true) { c = in.read(); if ( c == -1 ) { if (sb.length() == 0) { return null; } break; } if (c == '\n' || c == '\r') { break; } count++; if (count > max) { throw new IllegalArgumentException("Invalid readLine. Read more than maximum characters allowed (" + max + ")"); } sb.append((char) c); } return sb.toString(); } catch (IOException e) { throw new IllegalArgumentException( "Problem reading from input stream", e); } }
First Event
Last Event
HTTP Request
GET http://localhost:32771/grizzly/readline?param=testdata HTTP/1.1 Contrast-Mq-Name: queue-000-BufferedReaderIT.it_tests_unsafe_readline-contrastsecurity-docker.jfrog.io/contrast/buffered-reader:rev1 Host: localhost:32771 Connection: Keep-Alive Accept-Encoding: gzip User-Agent: okhttp/3.9.1