Cryptosense Analyzer finds Crypto Flaw in Java EE

Graham Steel
October 17, 2018

Yesterday's Oracle Critical Patch Update contains a credit to Cryptosense for CVE-2018-3210, a flaw found by one of our users while they were testing a Java application with our Analyzer software. The bug involves a repeating IV in AES-CTR mode, a crypto mistake that can be hard to spot in code review. Our run-time testing approach detects it more easily. It's also rather easy to exploit (see e.g. the Many-time Pad tool).

The result was reported to us by one of our customers, who asked us if we'd like to investigate since the issue didn't appear to come from their own code. We decided to ask the security group at Università Ca' Foscari, with whom we have a long-standing collaboration, if they could take a look. Leonardo Veronese carried out the work, and he takes up the story:Java Server Faces is a Framework for programming web application in the Java language and it's part of JavaEE (EnterpriseEdition). Through the Oracle JavaEE page it is possible to find and download the specification.The Oracle implementation of the specification is called mojarra and the source code is available on GitHub. The Project is part of EE4J initiative and it's being migrated to Eclipse Foundation.I looked at the source code of the classes that appeared on the stack trace sent to me by Cryptosense to find out what was the feature that they implemented and where the issue about AES-CTR was present. Inspecting the source code the class com.sun.faces.util.ByteArrayGuardAESCTR is used in the class com.sun.faces.context.flash.ELFlash which implements the interface javax.faces.context.Flash. From the docs:

The Flash concept is taken from Ruby on Rails and provides a way to pass temporary objects between the user views generated by the faces lifecycle. As in Rails, anything one places in the flash will be exposed to the next view encountered by the same user session and then cleared out. It is important to note that “next view” may have the same view id as the previous view.

So in short the flash is a way to store temporary data without using the session scope.

ByteArrayGuardAESCTR.java

This class is responsible for encryption and decryption. The method setupKeyAndCharset is called by the constructor and it is used to initialize objects. By default the key is generated through javax.crypto.KeyGenerator and the IV is generated with java.security.SecureRandom. The key and IV generated are stored in the object state.The first thing that can be considered as a vulnerability is the "non standard" initialization performed in the setupKeyAndCharset: if the FlashSecretKey property is specified, the key contained in there is used instead and, if this happens the IV is not randomly generated but is just equal to the key:

String encodedKeyArray = (String) 
context.lookup("java:comp/env/jsf/FlashSecretKey");
if (null != encodedKeyArray) {
	byte[] keyArray = DatatypeConverter.parseBase64Binary(encodedKeyArray);
  if (keyArray.length < 16) {
  throw new FacesException("key must be at least 16 bytes long.");
  }
  sk = new SecretKeySpec(keyArray, KEY_ALGORITHM);   
  byte[] iv = new byte[16];   
  System.arraycopy(keyArray, 0, iv, 0, 16);   
  ivspec = new IvParameterSpec(iv);
  }
  

ELFlash.java

In this class the ByteArrayGuardAESCTR is used, in fact a variable guard is defined and initialized in the constructor. Searching on this class for a new expression of ByteArrayGuardAESCTR only returns line 272 in the constructor, which means that the lifetime of the guard is bound to the lifetime of the ELFlash object.From the docs, it seems that the ELFlash object is created once in the application (and so the inner variables like flashInnerMap and guard). So it seems the IV is fixed for the lifetime of the application.

What's in the cookies?

In the ELFlash class a constant called FLASH_COOKIE_NAME is defined that contains csfcfc: The ciphertext is stored on a cookie. We can make a guess that some information about the flash are stored on a cookie to be retrieved after a redirect. The method encode creates the string to encrypt, encrypts it and then builds a cookie with it. From this we discover that the character _ is used as separator for the two encoded objects of the class FlashInfo. Each FlashInfo encoded information has a number, character X as a separator, then two letters that represent Lifetime and the mode.Looking at the decode method we can see that the cookie value is decrypted then used to restore the state by searching the sequence number on the inner map of the ELFlash instance.

Conclusions

The implementation of the Flash mechanism in Java Server Faces does contain a fixed IV in AES-CTR mode. An attacker could likely decrypt the ciphertexts in the cookies by observing several and applying knowledge of the structure of the plaintext. It's unlikely any confidential information would be stored in these short-term cookies, but a more interesting attack would be to tamper with the cookies to force the server to restore a different state than the one the user was supposed to go back to, possibly allowing access to states that would not have been available to him, and thereby circumventing security controls.