javaspringcheckmarx

Checkmarx Unchecked Input Loop from ServletRequest Input Stream


As part of an HttpServletRequestWrapper, I am accessing the input stream of the request content. Checkmarx is flagging this as Unchecked Input for Loop Condition, since the input stream is read using a while loop.

Checkmarx requires some validation on the input stream before it can be used in a loop - I've tried reading the input stream into a byte array and validate the array instead, but the flag is still raised on the input stream itself.

Here's how I'm accessing the input stream:

InputStream inputStream = request.getInputStream(); //this line is flagged by checkmarx
if (inputStream != null) {
   bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
   char[] charBuffer = new char[128];
   int bytesRead = -1;

   //while loop that reads an unchecked
   while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
      stringBuilder.append(charBuffer, 0, bytesRead);
   }
}

Of course there's no way to verify the length of the input stream before reading it, so how can I validate this input to pass checkmarx?

The checkmarx flag in question:

RequestWrapper gets user input from element getInputStream. This element’s value flows through the code without being validated, and is eventually used in a loop condition in RequestWrapper at line 31 of RequestWrapper.java.
This constitutes an Unchecked Input for Loop Condition.


Solution

  • This appears to be a case of the Unchecked_Input_for_Loop_Condition not recognizing Definite Assignment used as part of the loop validation criteria. On digging into the query, it has a comment that code like (stream.read() != -1) is a valid checking method, which is similar to your code.

    The query needs to be fixed, but in the meantime you have a few options:

    1. Mark the vulnerability as Not Exploitable
    2. Reform your code to not have the definite assignment in the loop condition. This code, for example, does not trigger the result:
    do
    {
        if ((bytesRead = bufferedReader.read(charBuffer) > 0)
          stringBuilder.append(charBuffer, 0, bytesRead);
    } while (bytesRead > 0);