Git Product home page Git Product logo

silverstripe-mfa's Introduction

MultiFactor Authentication for SilverStripe

CI Silverstripe supported module

With thanks to Simon Firesphere Erkelens

This module was based on pioneering work by Simon. It differs from the original implementation in its use of a pluggable React UI + JSON API architecture, and its enhanced management UI within the CMS. You can find Simon's original module here.

Installation

composer require silverstripe/mfa

Documentation

Read the documentation.

Module development

When adding translatable content to front-end UIs in the MFA module, you must ensure that these translations are pushed to Transifex. If this doesn't happen, they will be automatically removed in the next module released. See the translation docs for more information.

License

See license.

Versioning

This library follows Semver. According to Semver, you will be able to upgrade to any minor or patch version of this library without any breaking changes to the public API. Semver also requires that we clearly define the public API for this library.

All methods, with public visibility, are part of the public API. All other methods are not part of the public API. Where possible, we'll try to keep protected methods backwards-compatible in minor/patch versions, but if you're overriding methods then please test your work before upgrading.

Reporting issues

Please create an issue for any bugs you've found, or features you're missing.

silverstripe-mfa's People

Contributors

amolswnz avatar bergice avatar cheddam avatar chillu avatar dependabot[bot] avatar dnsl48 avatar emteknetnz avatar firesphere avatar github-actions[bot] avatar gurucomkz avatar guysartorelli avatar heyimphil avatar indygriffiths avatar maxime-rainville avatar michalkleiner avatar nightjar avatar robbieaverill avatar sabina-talipova avatar sachajudd avatar scopeynz avatar ssmarco avatar thebnl avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

silverstripe-mfa's Issues

Send email to admins when backup code is used

When a backup code is used, an admin should be notified.

AC's

  • When a user uses a backup code, an email is sent to the administrators
  • When a user logs in with backup codes X times in a row, the user is locked out
  • When a user logs in with a real MFA method, the lockout count is resetted
  • The behaviour is configurable/can be disabled

Force MFA on forgot password flow

If a member has a registered MFA method and a password reset is requested, the MFA needs to authenticate with their MFA method before the new password is stored.

Designs: https://projects.invisionapp.com/share/3PNSKZQYBJZ#/screens/325683174

ACs:

  • MFA authentication flow is accessible directly from password reset link (e.g one that is emailed)
  • Reset password page is outside of the React app
  • Reset password page has new styling as per the designs for Starter Theme/Wātea
  • New password is stored when flow is complete
  • User flow ends where current functionality for forgot password flow takes them

MFA cannot be disabled for site

A user is unable to disable MFA for a site using the mfa settings checkbox in site settings.

To reproduce:

  1. Access site settings, confirm mfa settings checkbox is unchecked
  2. Have a user who has not skipped registration log in
  3. Identify user is shown the MFA registration screen (bug)

Expected behaviour:
If the mfa settings is unchecked, no user will be presented with the mfa registration screen when logging in.

Version:
silverstripe/mfa dev-master 7c5ccba

Create container shell for the MFA app flow

This will be the entry point for MFA login (after the regular login) and be a container with a bunch of components to represent different screens, including third party components from MFA method modules (like TOTP).

ACs:

  • This could be triggered on a security URL , i.e Security/MFA
  • Example templates with example components are visible
  • Ability to transition between screens

Not to worry about yet:

  • Tying this to admin

Reject strings longer than expected

From Firesphere/silverstripe-bootstrapmfa#8

No matter what, with U2F, OTP or TOTP, the string is supposed to be an expected length. Anything not matching the length should be rejected for security reasons.

I believe this should be implemented as low level as possible. It can easily be done via a configuration setting of the module that bolts on top of the Bootstrapping.

Audit log when MFA has been used (success and fail)

We need to have a full audit log of user activities. This is already the case for "logged in" as well as "failed login" events. But it doesn't specifically register this in the context of backup codes. We should provide event hooks for https://github.com/silverstripe/silverstripe-auditor to pick up (and implement those listeners in the auditlog module)

ACs

  • MFA activities are logged to a point that it's useful for an auditing perspective
  • logged in an access restricted, append-only external logging service which is already part of CWP

Notes:

  • Initial list of MFA actions (may not definitive):
  • Success login, which method (including recovery codes)
  • Failed login, which method was attempted (including recovery codes)
  • Compounding failed attempts
  • Admin functions, like reseting backup codes, adding or removing registered methods
  • Skipped registration
  • This should cater for backend logs and db work. We'll handle any CMS views of this information in separate issue

Pull requests

Resend invite for new members

As a CMS admin, I want the ability to resend an invitation link for members who have not completed login registration, so that if the member updates their email address or did not receive the email I can send it again.

ACs

Designs: https://projects.invisionapp.com/share/3PNSKZQYBJZ#/screens/325486637

Add backup code method - backend

See https://github.com/Firesphere/silverstripe-bootstrapmfa/blob/master/src/Models/BackupCode.php

This will need a DataObject and an implementation of the MethodInterface etc interfaces.

Backup codes will be generated for a user (Member has_many BackupCodes) when their first MFA method is registered, or when they've asked for them to be reset via the admin area.

Designs:

Add back up code method - registration frontend

Backend work implemented in #4

ACs

  • Back up codes are generated after the successful registration of a method.
  • There is no confirmation of the codes required, they are simply displayed to the user once.
  • Back up codes are presented in a format that can be copied to the clipboard without loosing formatting.
  • There is a button to download the codes using JavaScript.
  • There is a button to copy the codes to the clipboard.
  • It should look good with the Wātea theme.
  • There is text describing back up codes as per the designs.
  • Use generic class names for buttons.

Designs
https://projects.invisionapp.com/share/3PNSKZQYBJZ#/screens/322766388

'Keep me signed in' extends to MFA

Expect we'll get this for free, but raising here so it's not lost.

Users already have the option to remember their login for x days on devices they trust, as an opt-in feature on the login form. This behaviour needs to be extended to MFA.

AC

  • A user with a registered MFA method who selects the 'Keep me signed in' option at the login form screen will not be prompted to log in with MFA on the same device within the configurable amount of days.

User can define primary method

As a CMS user who has multiple registered MFA methods, I want this ability to set a primary method, so that the next time I log in I am presented with my primary method as the first option.

ACs

  • The CMS user has the ability to do this in the CMS
  • Configuration in the CMS to set a primary method will be available for all methods that are currently registered and not the primary for the user
  • The first method to be registered will by default become the primary, unless changed by the CMS user.

Designs

Failed login count in CMS should include MFA

We should ensure that failed MFA attempts are captured in the CMS against a member, so that CMS admins can understand the state of attempted logins on a per user basis.

A suggestion is:

Currently there is a field for Failed Login Count. Failed MFA logins should be included in this count.

New CMS users can define own password

As a site owner, I want to provide the ability for users to set their own passwords, so that CMS admins are not defining passwords for users.

ACs

  • The CMS admin can still create new members
  • The CMS user has the ability to create their password before their first login
  • The solution decision takes into consideration sites that do not have email capability
  • The solution decision takes into consideration how this will work for UAT environments

Notes:

  • Expect this would be implemented at a framework level. We may need to think about the release process for this if MFA will be released in July.
  • So far there's been designs for two POCs:

Option 1 - note we won't be proceeding with this option
Create an 'invite' email:

  • At /admin/security/EditForm/field/Members/item/new the password field are removed
  • The 'Create' action is replaced with a 'Save and invite' action
  • On 'Save and invite' an invitation email is sent to the new user
  • An alert is presented in the CMS to notify the CMS admin that an email has been sent
  • The email provides an invitation link to complete the set up of a user, prompts to create a password in a login form
  • Designs: https://projects.invisionapp.com/share/3PNSKZQYBJZ#/screens/325486638
  • To support this flow there are issues written to handle 'pending' users, and reports to identify them. See #38 and #39

Option 2
Checkbox to require password reset:

Logic to make backup codes a 'back-up' method

A back-up method should:

  • Be a mandatory set-up process after you have set up at least one other MFA method
  • Should never be presented as the default MFA method

It might make sense to ensure that you are logged in after seeing registering backup codes while doing this task. Currently you aren't in a logged in state and have to use the MFA method you just set up.

Limit attempts on authentication methods

Our architecture document states:

Validation: Brute force attacks are mitigated by the existing CWP constraints around counting failed logins, and locking out the user for 15 minutes after 5 failed login attempts.

This appears within a section labelled "Shared Security Attributes" - all authentication methods share this rule.

We need to implement this mechanism for MFA - perhaps riding on the existing password attempt model.

A/Cs

  • Authentication method, regardless of implementation, has unsuccessful attempts tracked
  • The core API is used. Failings are shared between password failures and MFA failures towards a shared 'count'

These were ACs, but we should take what's provided in core first

  • User is blocked after 5 consecutive failed attempts - regardless of delay between attempts
  • A user is blocked for at least 15 minutes - this cannot be circumvented (by going incognito, clearing cookies, changing IP address etc)

Pull requests

Accessway - move login form to the CMS

Overview

There's been strong suggestions to remove all website authentication away from the frontend site, and into a CMS looking login form.

This isn't the first time this has been raised, but it's relevant as part of the MFA work as we currently come up with the change

Benefits

  • Frontend designers/developers do not need to be concerned with the styling of the site login form (especially when the majority of logins are for CMS access)
  • Removes the dependancy of relying on a theme to inherit styles (and potentially break) the original login form template
  • Create a consistent and professional gateway to log in to the CMS
  • Allows for a 'cleaner' approach for implementing an MFA flow for a site, removing the requirement to inject an MFA app into the SS page template.

Considerations

  • It's unlikely we'll want to build this into core before MFA is released with 4.4.x - so it should be handled in it's own module (https://github.com/silverstripe/silverstripe-login-forms/)
  • A configuration flag could be built to enable this
  • This should include all security frontend forms: forgot password, reset password, MFA registration, MFA login, etc.
  • There are examples in the current MFA flow where users in the CMS are prompted for MFA again. This flow will need to be considered too.

ACs

  • Create the template
  • Template includes the site name, SilverStripe logo
  • The template can be called with the framework config settings - it's auto enabled when the MFA module is installed (with the login-forms module being a requirement of the MFA module)
  • The MFA module plugs into this
  • Overriding the original login form form project code should be taken into consideration

Other options discussed

  1. Retain existing login form, on successful login, direct to MFA screen injected in the same page template
  2. Retain existing login form, on successful login, direct to MFA standalone screen
  3. A login modal on top of the site. This would likely be difficult to guarantee compatibility with all sites.

Option to select authentication method

As a CMS user registering a MFA method, I want to be able to chose which method to set up from available options, so that I can select my preferred method.

Designs: https://projects.invisionapp.com/share/3PNSKZQYBJZ#/screens/321189815

ACs

  • There is a selected state for verification methods
  • The template has an area to display information on the authentication methods (including 'Find out more' link) which will be surfaced from the authentication method's own components
  • The 'Next' button is disabled until a selection is made
  • Styling is created, as per designs, to disable authentication methods that may not be available. This would be attainted from the method module. An example being U2F is only supported by default in Chrome v71+ so it would otherwise be disabled in another browser
  • The user has the ability to go back to the previous screen
  • Area has the ability to stack up to three 'method' boxes wide
  • Create default styling within the app, using generic class names that could be overwritten by a site developer

Password update in CMS requires MFA

As a CMS admin with MFA enabled on my site, I want all users registered with MFA to be required to authenticate with a second factor when updating their password in the CMS, so that all CMS user details are secure.

ACs

  • Users with a registered MFA method will be required to authenticate with MFA when choosing to update their password in the CMS member settings.
  • Flow is:
    1. request to update password,
    2. MFA authentication required,
    3. on MFA success, forms to update password are presented
  • Uses the CMS modal functionality

Authenticate with recovery codes + update header styling

As a CMS user who has a registered MFA method, I want to be able to authenticate with recovery codes, so that I have a means for authenticating if other methods aren't accessible.

Designs: https://projects.invisionapp.com/share/3PNSKZQYBJZ#/screens/351007936

ACs

  • This screen is accessible via the 'More options' screen implemented in #43
  • Graphic is static
  • Next button is disabled until at least one character is entered
  • There is a general validation message if the recovery code entered has a) already been used, b) does not match a code, or c) is in an incorrect format
  • Ensure heading styling is as per designs. I.e. H1 is smaller

Changes to user's MFA should result in email

As a user with a registered MFA method, I would like to receive email notifications for all updates related to my MFA, so that if I receive an email referencing a change I am not aware of I can expect my account to be compromised and follow the recommended steps.

ACs

  • Any actions changing or resetting authentication mechanisms will trigger automated emails to the email address of the user
  • Email should make specific reference to the MFA method
  • Email should provide steps for the user to take if the change was not expected
  • Email template is theme-able

Notes

  • Examples of changing or reseting:
    a. MFA method is registered
    b. MFA method is removed
    c. Recovery codes are reset
    d. Recovery code is used
    e. One recovery code left?

Create some pluggable interface for modules to add JS/CSS requirements

Currently we have some declarative interfaces for plug-in authenticators for this module. What we haven't considered is the fact that these plug-in authenticators need to implement JavaScript (and probably CSS) but we have no way of including these client bundles as "requirements".

We need something for this. Perhaps we should add methods to our existing MethodInterface?

FYI when you almost run out of backupcodes

From @robbieaverill:

I think an FYI email might be a good idea, perhaps saying "please log in and reset your backup codes if you'd like to generate a new set" or something like that (wording TBC).

We could either do this with queuedjobs or with an extension point in the login process, but either way we'd probably only want to notify the user once (?) rather than every time they login, or the job runs.

Add default configuration for MFA authenticator

Currently users of this module should enable it by overriding the default authenticator provided by framework with the following config:

---
Name: mysitemfa
After: '#coresecurity'
---
SilverStripe\Core\Injector\Injector:
  SilverStripe\Security\Security:
    properties:
      Authenticators:
        default: %$SilverStripe\MFA\Authenticator\MemberAuthenticator

We should make this default configuration in this module so that there is no custom configuration required.

As there are no MFA methods as part of this module by default we will also have to ensure the whole MFA process is skipped given there are no MFA methods registered.

A/Cs:

  • Configuration is applied when this module is installed (#10)
  • Having no MFA methods installed & registered will skip the MFA part of login (#10)

More options screen

Screen to capture more options for authenticating if a method is not available.

Design: https://projects.invisionapp.com/share/3PNSKZQYBJZ#/screens/321189140

ACs

  • Graphic is static
  • 'Enter one of your recovery codes' option is always available
  • There is a static message "Contact your site administrator if you require your multi-factor authentication to be reset."
  • If a user has other methods registered with their account, options to use these will be shown here, with 'Verify with x'.

"session timed out" login dialog needs to works with MFA

We need to ensure that the login popup you get when you've logged out due to inactivity still works with MFA.

You can reproduce by logging out in a new tab then clicking on a page in the site tree.

Notes:

  • Requires the MFA modal or Sudo mode first

Base registration component handler doesn't care about non-200 results

If my MFA component's backend RegisterHandlerInterface implementation throws an exception during the register() method, the result is a 400 response, but the frontend components don't check for it and continue on to generating backup codes. This leaves the user registered with only back up codes. It should return an error on the frontend instead and allow the process to continue.

Acceptance criteria

  • Throwing an AuthenticationFailedException (doesn't exist in master at time of writing) from a RegisterHandler::register() method will be caught by the MFA frontend app
  • As above, will not proceed to generation of backup codes
  • As above, will pass the exception's message down to React registration components as a prop (e.g. { hasError: true, errorMessage: $ex->getMessage() } (pseudo code - example only)

Error state passed to login components is not unique

Example:

  • Register TOTP as your method
  • Login with it and enter an incorrect code
  • Choose More options
  • Select backup codes

Observe error state on the backup codes component. This should be reset when moving out of the login component.

Login handler supports providing the frontend app schema via endpoint

ACs

  • It's JSON
  • Doesn't need to be publicly accessible, can 404
  • Think about how this could work in a headless approach, or just use sticky sessions?
  • It takes the member from the session store for context
  • Add a fetch to the frontend app for this endpoint
  • Style has contributed to choosing loading indicator, note we wouldn't be using anything from admin at this point
  • There is handling if the API fails, with a message to the user. Note this is for system errors, not for failing authentication - that needs more thought
  • Return an empty object - writing the schema should be separate from this issue

Ability to reset recovery codes

As a CMS user with a registered MFA method, I want the ability to reset my recovery codes, so that if I loose them or if they are compromised I can access a new and secure set.

Backend work implemented in #4

ACs

  • Invokes the new modal, implemented in #46
  • There is the ability to reset recovery codes through the CMS member security form via a 'Reset recovery codes' action.
  • Selecting the 'Reset recovery codes' action presents a warning dialog to reset the codes.
  • Recovery codes can only be reset by the member which they are associated to.
  • On reset, the new recovery codes are displayed using the components created for the registration screen in #13
  • There is a button to download the codes using JavaScript.
  • There is a button to copy the codes to the clipboard.

Designs

Member MFA settings in CMS

User Story
As a CMS user, I want access to my MFA settings, so that I can manage my MFA details.

ACs

  • There is a new area of the member edit form for the user to manage their own MFA settings
  • New methods can be added from the settings
  • Existing methods can be removed
  • If MFA is mandatory, there is logic to ensure a user cannot remove their only registered method
  • Actions invoke the CMS modal

Designs
https://projects.invisionapp.com/share/3PNSKZQYBJZ#/screens/321186220

Notes

  • Reseting recovery codes was already captured in #35
  • Updating a primary method is captured in #66
  • The 'Sudo mode' implementation will handle the security gate to accessing these actions separately
  • Modal is built as part of #46

Allow users to skip MFA setup - Backend

Implement functionality so the MFA setup can be skipped

ACs

  • Functionality exists to 'skip' MFA setup after successful member login
  • Skip function is available if global grace period is enabled, and it has not ended, and the user does not have a registered method already;
  • Skip function is available if MFA is not mandatory
  • MFA registration will only be shown once if MFA is not mandatory, and has been skipped by the user already
  • If MFA is mandatory, and the grace period hasn't ended, registration is shown each time
  • No frontend work is required

MFA registration screen + skip registration

User story

As a CMS user without a registered MFA method, I want to be presented with a registration screen to set
up a MFA method up after I've logged in, so that I can add extra security to my CMS account.

Designs: https://projects.invisionapp.com/share/3PNSKZQYBJZ#/screens/321189816

ACs

  • This is the first page of the React app, displayed after a successful CMS login
  • This screen is only displayed to users without a registered MFA method
  • If MFA is mandatory, and the grace period hasn't ended, this registration screen is shown each time a user logs in
  • If MFA is non-mandatory, and the user has previously skipped registration, do not show this screen again
  • Functionality exists to 'set up later' as per notes below
  • Text in designs is static
  • Create default styling within the app, using generic class names that could be overwritten by a site developer

Skip functionality follows:

#14:

  • Skip function is available if global grace period is enabled and it has not ended
  • Skip function is available if MFA is not mandatory
  • Skip function is hidden if MFA is mandatory and global grace period has ended

Handle unavailable method in more options screen

User story
As a user trying to verify through the 'more options' screen, I want to know if an authentication method is not available based on my browser requirements, so that I don't select an option to verify that won't work in my scenario.

ACs

  • A user trying to use this method in the MFA flow is given information as to why it won't work with their browser, and is blocked from using it
  • Methods that are unavailable are disabled from selection

Notes

Pull requests

Ability to reset account

User Story
As a CMS admin, I want the ability to reset a CMS member's password and MFA registration, so that if the member looses all access to MFA methods or they have been compromised I can reset this.

ACs

  • A CMS (admin) has the ability to reset a user account via the user's member settings page
  • On clicking the option to reset the account, a dialog box is presented to confirm the action
  • On confirmation of the dialog box, an account reset email is sent to the user
  • There is information showing the sending status of the email
  • The account details won't be reset until the user accesses the link in the email
  • The email link has an expiry limit
  • The user receives an email containing a valid reset link
  • The user can visit that link and reset their password
  • Once they reset their password, their existing registered MFA methods are removed
  • They are then prompted to register a new MFA method

Designs: https://projects.invisionapp.com/share/3PNSKZQYBJZ#/screens/321186221

Increase strength of recovery codes

The current implementation of recovery codes is too weak (six numeric characters). The entropy needs to be increased.

ACs

  • Generation of codes meets the requirements laid out in NIST Special Publication 800-63B Digital Identity Guidelines, 5.1.2 Look-Up Secrets
  • Meets the requirements laid out in the internal SAD, 4.5.4 Cryptography and Security
  • Increasing the default amount of recovery codes generated has been investigated and a decision made
  • It has been considered whether new a 'recovery code' graphic is needed (current one only show six asterisks)

Update UI for responsive view

Overview
In order to provide the best UI for reduced screen sizes, some changes to the existing UI could be made.

Tasks for mobile view

  • Remove registration method graphics, stack options vertically one option wide
  • .

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.