Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Java input classes such as Scanner and BufferedInputStream facilitate fast, non-blocking nonblocking I/O by buffering an underlying input stream. Programs can create multiple wrappers on an InputStream. Programs that use multiple wrappers around a single input stream, however, can behave unpredictably depending on whether the wrappers allow look-ahead. An attacker can exploit this difference in behavior by, for example, redirecting System.in (from a file) or by using the System.setIn() method to redirect System.in. In general, any input stream that supports non-blocking nonblocking buffered I/O is susceptible to this form of misuse.

...

Code Block
bgColor#ccccff
public final class InputLibrary {
  private static BufferedInputStream in =
      new BufferedInputStream(System.in);

  public static char getChar() throws EOFException, IOException {
    int input = in.read();
    if (input == -1) {
      throw new EOFException();
    }
    in.skip(1); // This statement is to advance to the next line
                // The noncompliant code example deceptively
                // appeared to work without it (in some cases)
    return (char)input;
  }

  public static void main(String[] args) {
    try {
      System.out.print("Enter first initial: ");
      char first = getChar();
      System.out.println("Your first initial is " + first);
      System.out.print("Enter last initial: ");
      char last = getChar();
      System.out.println("Your last initial is " + last);
    } catch (EOFException e) {
      System.err.println("ERROR");
      // Forward to handler
    } catch (IOException e) {
       System.err.println("ERROR");
       // Forward to handler
    }
  }
}

...

This program was compiled under Java 1.6.0. When run from the command line, the program successfully takes two characters as input and prints them out. Unlike the NCCEnoncompliant code example, this program also produces correct output when run with a file redirected to standard input.

Compliant Solution (Accessible Class Variable)

If another class needs a program intends to use System.in as well as the InputLibrary class, the class program must use the same buffered wrapper used by InputLibrary, as does this class rather than creating and using its own additional buffered wrapper. Consequently, the InputLibrary class must provide make available a reference to its the buffered wrapper for such classesto support this functionality.

Code Block
bgColor#ccccff
public final class InputLibrary {
  private static BufferedInputStream in =
     new BufferedInputStream(System.in);

  static BufferedInputStream getBufferedWrapper() {
    return in;
  }

  // ...other methods
}


// Some code that requires user input from System.in
class AppCode {
  private static BufferedInputStream in;

  AppCode() {
    in = InputLibrary.getBufferedWrapper();
  }

  // ...other methods
}

...

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="5e1c4859dd204c8f-f49d3662-410049ed-be81bb71-9ec4cba74298657808d56d95"><ac:plain-text-body><![CDATA[

[[API 2006

AA. Bibliography#API 06]]

[method Method read

http://java.sun.com/javase/6/docs/api/java/io/InputStream.html#read()]

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="5fe310aed54e6ede-78e4ed5a-418145fa-8725a26b-88fc7706cc24978afe0b277c"><ac:plain-text-body><![CDATA[

[[API 2006

AA. Bibliography#API 06]]

[class Class BufferedInputStream

http://java.sun.com/javase/6/docs/api/java/io/BufferedInputStream.html]

]]></ac:plain-text-body></ac:structured-macro>

...