Home » Content Editor » Enforce Password Expiration in the Sitecore CMS

Enforce Password Expiration in the Sitecore CMS

Sitecore Technology MVP 2016
Sitecore MVP 2015
Sitecore MVP 2014

Enter your email address to follow this blog and receive notifications of new posts by email.

I recently worked on a project that called for a feature to expire Sitecore users’ passwords after an elapsed period of time since their passwords were last changed.

The idea behind this is to lessen the probability that an attacker will infiltrate a system — or multiple systems if users reuse their passwords across different applications (this is more common than you think) — within an organization by acquiring old database backups containing users’ passwords.

Since I can’t show you what I built for that project, I cooked up another solution — a custom loggingin processor that determines whether a user’s password has expired in Sitecore:

using System;
using System.Web.Security;

using Sitecore.Diagnostics;
using Sitecore.Pipelines.LoggingIn;
using Sitecore.Web;

namespace Sitecore.Sandbox.Pipelines.LoggingIn
{
    public class CheckPasswordExpiration
    {
        private TimeSpan TimeSpanToExpirePassword { get; set; }
        private string ChangePasswordPageUrl { get; set; }

        public void Process(LoggingInArgs args)
        {
            Assert.ArgumentNotNull(args, "args");
            if (!IsEnabled())
            {
                return;
            }

            MembershipUser user = GetMembershipUser(args);
            if (HasPasswordExpired(user))
            {
                WebUtil.Redirect(ChangePasswordPageUrl);
            }
        }

        private bool IsEnabled()
        {
            return IsTimeSpanToExpirePasswordSet() && IsChangePasswordPageUrlSet();
        }

        private bool IsTimeSpanToExpirePasswordSet()
        {
            return TimeSpanToExpirePassword > default(TimeSpan);
        }

        private bool IsChangePasswordPageUrlSet()
        {
            return !string.IsNullOrWhiteSpace(ChangePasswordPageUrl);
        }

        private static MembershipUser GetMembershipUser(LoggingInArgs args)
        {
            Assert.ArgumentNotNull(args, "args");
            Assert.ArgumentNotNullOrEmpty(args.Username, "args.Username");
            return Membership.GetUser(args.Username, false);
        }

        private bool HasPasswordExpired(MembershipUser user)
        {
            return user.LastPasswordChangedDate.Add(TimeSpanToExpirePassword) <= DateTime.Now;
        }
    }
}

The processor above ascertains whether a user’s password has expired by adding a configured timespan — see the configuration file below — to the last date and time the password was changed, and if that date and time summation is in the past — this means the password should have been changed already — then we redirect the user to a change password page (this is configured to be the Change Password page in Sitecore).

I wired up the custom loggingin processor, its timespan on expiring passwords — here I am using 1 minute since I can’t wait around all day 😉 — and set the change password page to be the url of Sitecore’s Change Password page:

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <processors>
      <loggingin>
        <processor mode="on" type="Sitecore.Sandbox.Pipelines.LoggingIn.CheckPasswordExpiration, Sitecore.Sandbox"
					patch:before="processor[@type='Sitecore.Pipelines.LoggingIn.CheckStartPage, Sitecore.Kernel']">
          <!-- Number of days, hours, minutes and seconds after the last password change date to expire passwords -->
          <TimeSpanToExpirePassword>00:00:01:00</TimeSpanToExpirePassword>
          <ChangePasswordPageUrl>/sitecore/login/changepassword.aspx</ChangePasswordPageUrl>
        </processor>  
      </loggingin>
    </processors>
  </sitecore>
</configuration>

Let’s test this out.

I went to Sitecore’s login page, and entered my username and password on the login form:

login-page

I clicked the Login button, and was redirected to the Change Password page as expected:

change-password-page

If you can think of any other security measures that should be added to Sitecore, please share in a comment.

Advertisement

5 Comments

  1. Nico Lubbers says:

    one of the improvements that could be added as well, is to validate that the new password meets certain criteria like strength and a history trail (password cannot be re-used in let’s say the next 10 times)

    • Excellent ideas!

      Setting the following attributes on /configuration/system.web/membership/providers/add[@name=”sql”] in the Web.config would increase password strength:

      • MinRequiredNonAlphanumericCharacters
      • MinRequiredPasswordLength
      • PasswordStrengthRegularExpression

      We might need to create a custom System.Web.Security.MembershipProvider to ascertain whether a password was used in the past — this could leverage a custom data-store that would keep track of previous passwords for users.

  2. Dipak Yadav says:

    Password in database always save in encrypted format so there is already we have the security with sitecore, if you want to enforce the password should be change the use domain security for this.

    • Although passwords are encrypted in the ASP.NET Membership tables, a cracker could easily write a program using logic defined in GetPasswordWithFormat() and EncodePassword() defined in System.Web.Security.SqlMembershipProvider — assuming this “out of the box” MembershipProvider is being used — to “guess” passwords from a “dictionary” of words.

  3. Martin Bryce says:

    By establishing minimum complexity requirements, you’re going to foil any dictionary-based checking. If you are paranoid, you could check a potential password against a “dictionary” containing not only actual words, but common passwords.

Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: