Versions Compared

Key

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

...

  • uses objects to store sensitive data whose values contents are not cleared or garbage collected after use
  • has memory pages that can be swapped out to disk as required by the operating system (to perform memory management tasks and to support hibernation)
  • uses any buffers to hold sensitive data (such as BufferedReader). The OS cache and in the in-memory copy of the data are also retained in this case.
  • bases its control flow on Reflection that circumvents allows circumventing any countermeasures to limit the lifetime of sensitive variables
  • reveals sensitive data in debugging messages, log files, environment variables or through thread dumps and core dumps

...

This noncompliant code example reads login information from the console and stores the password as a String object. Consequently, the password credentials may remain exposed until the garbage collector reclaims the memory associated with the object String objects.

Code Block
bgColor#FFCCCC
class BadPassword {
  public static void main (String args[]) throws IOException {
    Console c = System.console();
      if (c == null) {
        System.err.println("No console.");
        System.exit(1);
      }

      String login = c.readLine("Enter your user name: ");
      String password = c.readLine("Enter your password: ");

      if (!verify(login, password)) {
        throw new IOException("Invalid Credentials");     
      }
      // ...
  }

  // dummyDummy verify method, always returns true   
  private static final boolean verify(String login, String password) {
    return true;
  }
}

...

Code Block
bgColor#ccccff
class GoodPassword {
  public static void main (String args[]) throws IOException {
    Console c = System.console();
    
    if (c == null) {
      System.err.println("No console.");
      System.exit(1);
    }

    String login = c.readLine("Enter your user name: ");
    char [] password = c.readPassword("Enter your password: ");
  
    if (!verify(login, password)) {
      throw new IOException("Invalid Credentials");     
    }
  
    // ... Clear the password
    Arrays.fill(password, ' ');
  }

  // dummyDummy verify method, always returns true   
  private static final boolean verify(String login, char[] password) {
    return true;
  }
}

...

Code Block
bgColor#FFCCCC
BufferedReader br = new BufferedReader(new InputStreamReader(
  new FileInputStream("file")));
// readRead from the file

Compliant Solution

This compliant solution uses a direct allocated NIO buffer to read sensitive data from the file. The data can be cleared immediately after use and is not cached or buffered in at multiple locations. It exists only in the system memory.

Code Block
bgColor#ccccff
private void readIntoDirectBuffer() throws IOException {
  ByteBuffer buffer = ByteBuffer.allocateDirect(16*1024);
  FileChannel rdr = (new FileInputStream("file")).getChannel();
  while(rdr.read(buffer) > 0) {
    // doDo something with the buffer
    buffer.clear();
  }
  rdr.close();
}

...