CAS Vulnerability Disclosure


Remember

This post is NOT new. I am just collecting it here so it’s publicly available. This was originally published as a secret gist on Github in April 2016.

Overview

This is an Apereo CAS project vulnerability disclosure, describing an issue in CAS’s attempts to deserialize objects via the Apache Commons Collections library.

Affected Deployments

The attack vector specifically applies to all deployments of CAS v4.1.x and v4.2.x deployments where the out-of-the-box default configuration of CAS is used for managing object serialization, encryption and signing of data.

You are NOT affected by this issue, if:

  • You have deployed a different CAS version, lower than v4.1.0.
  • You have deployed CAS v4.1.x or v4.2.x, BUT you have removed the default CAS configuration for encryption/signing and have regenerated the appropriate settings for your own deployment.

Exploiting the vulnerability hinges on getting the JVM to de-serialize Java objects from arbitrary serialized data. If the above conditions describe your deployment, we STRONGLY recommend that you take necessary action to patch your deployment based on the below instructions.

Severity

This is a very serious issue where successfully exercising this vulnerability allows the adversary to inject arbitrary code. This disclosure is about a specific exploit path involving a bugged version of Apache Commons Collections. This exploit path is only an instance of a larger JVM Java object deserialization security concern.

Patching

Patch releases are now available to address CAS v4.1.x and v4.2.x deployments. Upgrades to the next patch version for each release should be a drop-in replacement, with some effort to appropriately reconfigure CAS encryption/signing settings via the cas.properties file.

CAS 4.1.x

Overlay

Modify your CAS overlay to point to version 4.1.7.

A snippet of a pom.xml for a CAS overlay follows:

...

<dependencies>
    <dependency>
        <groupId>org.jasig.cas</groupId>
        <artifactId>cas-server-webapp</artifactId>
        <version>${cas.version}</version>
        <type>war</type>
        <scope>runtime</scope>
    </dependency>
</dependencies>

<properties>
    <cas.version>4.1.7</cas.version>
</properties>
...

TGC Settings

Locate your cas.properties file and find the tgc.* settings.

  • If your CAS deployment is NOT using the default encryption/signing keys provided by CAS and you have regenerated new keys and have replaced the default, you can safely ignore this step and leave your key configuration of signing/encryption in place without any further changes.

  • If your CAS deployment IS using the default encryption/signing keys provided by CAS and you have NOT regenerated new keys to replace the default, you MUST take action to regenerate the keys.

You can choose one of the two approaches described below to handle key regeneration.

1) Let CAS Generate Keys

Blank/comment out the following tgc settings:

# tgc.encryption.key=
# tgc.signing.key=

Build and deploy your CAS deployment once. Upon startup, CAS will notice that no keys are defined, and it will appropriately generate keys for you automatically. Your CAS logs will then show the following snippet:

WARN [org.jasig.cas.util.BaseStringCipherExecutor] - <Secret key for encryption is not defined. CAS will attempt to auto-generate the encryption key>
WARN [org.jasig.cas.util.BaseStringCipherExecutor] - <Generated encryption key ABC of size ... . The generated key MUST be added to CAS settings.>
WARN [org.jasig.cas.util.BaseStringCipherExecutor] - <Secret key for signing is not defined. CAS will attempt to auto-generate the signing key>
WARN [org.jasig.cas.util.BaseStringCipherExecutor] - <Generated signing key XYZ of size ... . The generated key MUST be added to CAS settings.>

You should then grab each generated key for encryption and signing, and put them inside your cas.properties file for each now-enabled setting:

tgc.encryption.key=ABC
tgc.signing.key=XYZ

2) Manually Generate Keys

Using a git client, clone and build the following project:

git clone https://github.com/mitreid-connect/json-web-key-generator.git
cd json-web-key-generator
mvn clean package
cd target

# Encryption Key
java -jar json-web-key-generator-0.3-SNAPSHOT-jar-with-dependencies.jar -t oct -s 256

#
# Full key:
# {
#   "kty": "oct",
#   "k": "ABC"
# }
#

# Signing Key
java -jar json-web-key-generator-0.3-SNAPSHOT-jar-with-dependencies.jar -t oct -s 512

# Full key:
# {
#   "kty": "oct",
#   "k": "XYZ"
# }

You should then grab each generated key for encryption and signing, and put them inside your cas.properties file for each now-enabled setting:

tgc.encryption.key=ABC
tgc.signing.key=XYZ

Webflow Settings

Locate your cas.properties file and find the webflow.* settings. If you do not see them in your configuration, go ahead and define them:

# webflow.encryption.key=
# webflow.signing.key=

You can choose one of the two approaches described below to handle key regeneration.

1) Let CAS Generate Keys

Blank/comment out the following webflow settings:

# webflow.encryption.key=
# webflow.signing.key=

Build and deploy your CAS deployment once. Upon startup, CAS will notice that no keys are defined, and it will appropriately generate keys for you automatically. Your CAS logs will then show the following snippet:

WARN [org.jasig.cas.util.BinaryCipherExecutor] - <Secret key for encryption is not defined. CAS will attempt to auto-generate the encryption key>
WARN [org.jasig.cas.util.BinaryCipherExecutor] - <Generated encryption key ABC of size ... . The generated key MUST be added to CAS settings.>
WARN [org.jasig.cas.util.BinaryCipherExecutor] - <Secret key for signing is not defined. CAS will attempt to auto-generate the signing key>
WARN [org.jasig.cas.util.BinaryCipherExecutor] - <Generated signing key XYZ of size ... . The generated key MUST be added to CAS settings.>

You should then grab each generated key for encryption and signing, and put them inside your cas.properties file for each now-enabled setting:

webflow.encryption.key=ABC
webflow.signing.key=XYZ

2) Manually Generate Keys

Using a git client, clone and build the following project:

git clone https://github.com/mitreid-connect/json-web-key-generator.git
cd json-web-key-generator
mvn clean package
cd target

# Encryption Key
java -jar json-web-key-generator-0.3-SNAPSHOT-jar-with-dependencies.jar -t oct -s 96

#
# Full key:
# {
#   "kty": "oct",
#   "k": "ABC"
# }
#

# Signing Key
java -jar json-web-key-generator-0.3-SNAPSHOT-jar-with-dependencies.jar -t oct -s 512

# Full key:
# {
#   "kty": "oct",
#   "k": "XYZ"
# }

You should then grab each generated key for encryption and signing, and put them inside your cas.properties file for each now-enabled setting:

webflow.encryption.key=ABC
webflow.signing.key=XYZ

XML Configuration

If you have manually overridden the cas-servlet.xml file, you will need to make sure the following blocks are present in the configuration:


Note that the Person Directory project requires the following configuration in CAS overlays:

```xml

Note that the Person Directory project requires the following configuration in CAS overlays:

```xml
<bean id="loginFlowStateTranscoder" class="org.jasig.spring.webflow.plugin.EncryptedTranscoder"
        c:cipherBean-ref="loginFlowCipherBean" />

<bean id="loginFlowCipherBean" class="org.jasig.cas.web.flow.CasWebflowCipherBean"
    c:cipherExecutor-ref="webflowCipherExecutor" />

<bean id="webflowCipherExecutor" class="org.jasig.cas.util.BinaryCipherExecutor"
    c:encryptionSecretKey="${webflow.encryption.key:}"
    c:signingSecretKey="${webflow.signing.key:}"/>

Re-adjust the beans accordingly, and remove the built-in keystore.

Finally

Rebuild and redeploy your CAS overlay.

CAS 4.2.x

Modify your CAS overlay to point to version 4.2.1.

A snippet of a pom.xml for a CAS overlay follows:

...

<dependencies>
    <dependency>
        <groupId>org.jasig.cas</groupId>
        <artifactId>cas-server-webapp</artifactId>
        <version>${cas.version}</version>
        <type>war</type>
        <scope>runtime</scope>
    </dependency>
</dependencies>

<properties>
    <cas.version>4.2.1</cas.version>
</properties>
...

TGC Settings

Locate your cas.properties file and find the tgc.* settings.

  • If your CAS deployment is NOT using the default encryption/signing keys provided by CAS and you have regenerated new keys and have replaced the default, you can safely ignore this step and leave your key configuration of signing/encryption in place without any further changes.

  • If your CAS deployment IS using the default encryption/signing keys provided by CAS and you have NOT regenerated new keys to replace the default, you MUST take action to regenerate the keys.

You can choose one of the two approaches described below to handle key regeneration.

1) Let CAS Generate Keys

Blank/comment out the following tgc settings:

# tgc.encryption.key=
# tgc.signing.key=

Build and deploy your CAS deployment. Upon startup, CAS will notice that no keys are defined, and it will appropriately generate keys for you automatically. Your CAS logs will then show the following snippet:

WARN [org.jasig.cas.util.BaseStringCipherExecutor] - <Secret key for encryption is not defined. CAS will attempt to auto-generate the encryption key>
WARN [org.jasig.cas.util.BaseStringCipherExecutor] - <Generated encryption key ABC of size ... . The generated key MUST be added to CAS settings.>
WARN [org.jasig.cas.util.BaseStringCipherExecutor] - <Secret key for signing is not defined. CAS will attempt to auto-generate the signing key>
WARN [org.jasig.cas.util.BaseStringCipherExecutor] - <Generated signing key XYZ of size ... . The generated key MUST be added to CAS settings.>

You should then grab each generated key for encryption and signing, and put them inside your cas.properties file for each now-enabled setting:

tgc.encryption.key=ABC
tgc.signing.key=XYZ

Rebuild and redeploy your CAS overlay.

2) Manually Generate Keys

Using a git client, clone and build the following project:

git clone https://github.com/mitreid-connect/json-web-key-generator.git
cd json-web-key-generator
mvn clean package
cd target

# Encryption Key
java -jar json-web-key-generator-0.3-SNAPSHOT-jar-with-dependencies.jar -t oct -s 256

#
# Full key:
# {
#   "kty": "oct",
#   "k": "ABC"
# }
#

# Signing Key
java -jar json-web-key-generator-0.3-SNAPSHOT-jar-with-dependencies.jar -t oct -s 512

# Full key:
# {
#   "kty": "oct",
#   "k": "XYZ"
# }

You should then grab each generated key for encryption and signing, and put them inside your cas.properties file for each now-enabled setting:

tgc.encryption.key=ABC
tgc.signing.key=XYZ

Webflow Settings

Locate your cas.properties file and find the webflow.* settings. If you do not see them in your configuration, go ahead and define them:

# webflow.encryption.key=
# webflow.signing.key=

You can choose one of the two approaches described below to handle key regeneration.

1) Let CAS Generate Keys

Blank/comment out the following webflow settings:

# webflow.encryption.key=
# webflow.signing.key=

Build and deploy your CAS deployment once. Upon startup, CAS will notice that no keys are defined, and it will appropriately generate keys for you automatically. Your CAS logs will then show the following snippet:

WARN [org.jasig.cas.util.BinaryCipherExecutor] - <Secret key for encryption is not defined. CAS will attempt to auto-generate the encryption key>
WARN [org.jasig.cas.util.BinaryCipherExecutor] - <Generated encryption key ABC of size ... . The generated key MUST be added to CAS settings.>
WARN [org.jasig.cas.util.BinaryCipherExecutor] - <Secret key for signing is not defined. CAS will attempt to auto-generate the signing key>
WARN [org.jasig.cas.util.BinaryCipherExecutor] - <Generated signing key XYZ of size ... . The generated key MUST be added to CAS settings.>

You should then grab each generated key for encryption and signing, and put them inside your cas.properties file for each now-enabled setting:

webflow.encryption.key=ABC
webflow.signing.key=XYZ

2) Manually Generate Keys

Using a git client, clone and build the following project:

git clone https://github.com/mitreid-connect/json-web-key-generator.git
cd json-web-key-generator
mvn clean package
cd target

# Encryption Key
java -jar json-web-key-generator-0.3-SNAPSHOT-jar-with-dependencies.jar -t oct -s 96

#
# Full key:
# {
#   "kty": "oct",
#   "k": "ABC"
# }
#

# Signing Key
java -jar json-web-key-generator-0.3-SNAPSHOT-jar-with-dependencies.jar -t oct -s 512

# Full key:
# {
#   "kty": "oct",
#   "k": "XYZ"
# }

You should then grab each generated key for encryption and signing, and put them inside your cas.properties file for each now-enabled setting:

webflow.encryption.key=ABC
webflow.signing.key=XYZ

Finally

Rebuild and redeploy your CAS overlay.

Clustered CAS Deployments

If you are running a cluster of CAS nodes, please be advised that the newly generated keys for all settings (regardless of the method of generation, whether CAS or you) MUST be shared with all CAS nodes in form of either a centralized or replicated/shared cas.properties file.

Failure to do so will completely break CAS functionality.

If you only have a single-node CAS deployment, there is nothing further for you to do.

Support

If you have questions on the details this vulnerability and how it might be reproduced, please contact security@apereo.org or cas-appsec-public@apereo.org.

Resources

Misagh Moayyed

Related Posts

CAS 6.0.0 RC3 Feature Release

...in which I present an overview of CAS 6.0.0 RC3 release.

Apereo CAS - Multifactor Authentication with RADIUS

Learn how Apereo CAS may be configured to trigger multifactor authentication using a RADIUS server and its support for the Access-Challenge response type.

CAS Vulnerability Disclosure

Disclosure of a security issue with the MFA features.

CAS 6.0.0 RC2 Feature Release

...in which I present an overview of CAS 6.0.0 RC2 release.

Apereo CAS - dotCMS SAML2 Integration

Learn how to integrate dotCMS, a Content Management System and Headless CMS, with Apereo CAS running as a SAML2 identity provider.

Effective Software Troubleshooting Tactics

A collection of what hopefully are obvious troubleshooting tactics when it comes to diagnosing software deployment issues and configuration problems.

Apereo CAS - MaxMind Geo2IP ISP Integration

Learn how you may determine the Internet Service Provider, organization name, and autonomous system organization and number associated with the user's IP address in CAS using MaxMind services and present warnings in the authentication flow for the end-user if an IP address is matched.

Notes from Better by Design 2018

Be interested in humans and human success.

Apereo CAS - Authentication Lifecycle Phases

Tap into the Apereo CAS authentication engine from outside, and design extensions that prevent an unsuccessful authentication attempt or warn the user after-the-fact based on specific policies of your choosing.

CAS 6.0.0 RC1 Feature Release

...in which I present an overview of CAS 6.0.0 RC1 release.