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 RC2 Feature Release

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

CAS 6.0.0 RC1 Feature Release

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

Apereo CAS Delegated Authentication with ADFS

Learn how your Apereo CAS deployment may be configured to delegate authentication to Microsoft ADFS.

Apereo CAS Swag with Swagger

Enable Swagger integration with your Apereo CAS APIs.

Get Productive with Shell Aliases

A collection of useful shell aliases, gathered over the years to help increase one's productivity and developer happiness.

feat(conventional_commits): signal breaking changes in commit titles

In which I suggest Conventional Commits should be enhanced to reflect the breakingness of commits in their commit message titles.

uPortal annual report, June 2018 edition

Ecoysystem. Releases. Community. Fiscal responsibility.

One Can Only Hope in Buchistan

A true story inspired by real events. Seriously. Bryan Cranston has been approached for the role of "Some".

Apereo CAS - Extending Webflows

Learn and master extending CAS 5 Spring Webflow definitions.

Apereo CAS - Administrative Endpoints & Monitoring

Gain insight into your running Apereo CAS deployment in production. Learn how to monitor and manage the server by using HTTP endpoints and gather metrics to diagnose issues and improve performance.