Apereo CAS - Have you been pawned?


Collaborate
The blog is managed and hosted on GitHub. If you wish to update the contents of this post or if you have found an inaccuracy and wish to make corrections, we recommend that you please submit a pull request to this repository.

Have I been pwned is an online service that tracks security breaches and other datalogs on the internet, allowing you to check if your passwords linked to an email have been compromised. This is a very simple method and does not guarantee that your stuff is safe, or will continue to be safe. It does, however, allow you to have an idea of when data linked to your accounts might have been exposed, and whether you changed (or not) your passwords since that point.

A CAS deployment, as an entity that can support username/password credentials, can be integrated with this service such that after the user logs in with a valid password, CAS may check it against the service API and present a page to the user notifying them if their password has been pwned suggesting they should change it, but allow them to continue.

This sort of thing is fairly simple to do in CAS and while there are a variety of ways to tap into the authentication flow, in this post we shall take advantage of the CAS authenticator post-processors supported by a Groovy script. Our starting position is based on the following:

Configuration

First, we are going to teach CAS about the Groovy script that is to contact the relevant APIs and check for a pawned password:

cas.authn.engine.groovyPostProcessor.location=file:/etc/cas/config/GroovyPostProcessor.groovy

Our script itself may look like this:

import org.apereo.cas.*
import org.apereo.cas.authentication.*
import org.apereo.cas.authentication.credential.*
import java.net.*

def run(Object[] args) {
    def builder = args[0]
    def transaction = args[1]
    def logger = args[2]

    def credential = transaction.getPrimaryCredential().get()
    def password = credential.password
    def passwordSha1 = password.digest('SHA-1').toUpperCase()
    
    /*
        Contact the API using the SHA-1 digest of the credential password.
        Parse through the results, check for matches and produce a warning 
        where appropriate.
     */

    if (passwordHasBeenPawned()) {
        builder.addWarning(new DefaultMessageDescriptor("password.pawned"))  
    }
}

def supports(Object[] args) {
    def credential = args[0]
    def logger = args[1]
    credential instanceof UsernamePasswordCredential
}

Of course, the CAS message/language bundle (typically custom_messages.properties file) should also contain the text for the warning code password.pawned:

password.pawned=Your password is commonly used. Go <a href="https://example.org">here</a> to change it.

Note that the script itself is automatically monitored and cached for changes, so feel free to tweak and update as often as needed to test your changes without restarting the CAS server environment.

Finale

I hope this review was of some help to you and I am sure that both this post as well as the functionality it attempts to explain can be improved in any number of ways. Please feel free to engage and contribute as best as you can.

Misagh Moayyed

Related Posts

CAS 6.2.0 RC3 Feature Release

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

Checking Out Pull Requests Locally

Check out GitHub pull requests as local branches using a simple bash function.

CAS 6.2.0 RC2 Feature Release

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

Apereo CAS - Authentication Handler Resolution

Learn how to resolve and select authentication handlers based on configurable and flexible filtering criteria.

CAS Vulnerability Disclosure

Disclosure of a security issue with the CAS software.

Apereo CAS - SAML2 Metadata Overrides

Learn how to manage SAML2 service provider registrations in CAS and override metadata artifacts on a per-application basis.

Apereo CAS - Managing Configuration Metadata

Learn how to manage CAS configuration and properties using Spring Boot Configuration metadata.

CAS 6.2.0 RC1 Feature Release

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

Apereo CAS - Deployment Using systemd

Fabio Martelli of Tirasa S.r.l reviews the setup required to deploy Apereo CAS as a system service using systemd.

Apereo CAS - Python Locust Load Testing

Learn to Performance Test Apereo CAS with Python Locust.