Firestore security rules for 2FA

Viewed 887

I'm building a serverless app with Firebase: Firestore and cloud functions. One thing I've been struggling with is how to validate that a user has 2FA enabled to allow access to certain functions. Already enrolled into Google Identity Platform to allow 2FA, unfortunately I wasn't able to find an option to force 2FA.

My security rules requirements are: logged in, email verified, did authenticate with 2FA.

Current security rules in cloud firestore :

request.auth != null && request.auth.token.email_verified

As far as I've searched request.auth.token.phone_number can be checked, but that only checks if the user has registered a phone number, not if they have 2FA login?

2 Answers

After taking this question to google groups for support, I found the answer:

if request.auth.token.firebase.get('sign_in_second_factor', null) == 'phone'
&& 'second_factor_identifier' in request.auth.token.firebase;

This will allow access if user has mobile phone as 2FA.

You can view the original by Sam on google groups: https://groups.google.com/g/firebase-talk/c/7EZfxETa_jk/m/4e0FRCpWAgAJ

Google added Multi-factor authentication support to Google Cloud Identity Platform projects back in March last year. As an example, to authenticate a user, you can structure your code to include the following steps:

  1. Re-authenticate, the user;
  2. Ask the user to enter their phone number;
  3. Initialise: the reCAPTCHA verifier;
  4. Get a multi-factor session for the user;
  5. Initialise: a PhoneInfoOptions object with the user's phone number and the multi-factor session;
  6. Send a verification message to the user's phone;
  7. If the request fails, reset the reCAPTCHA;
  8. Ask the user to verify the SMS code;
  9. Initialise: a MultiFactorAssertion object;
  10. Complete the enrollment;

You can find the code snippet below on the Firebase documentation page if you are interested in reading more.

var recaptchaVerifier = new firebase.auth.RecaptchaVerifier(container);
user.multiFactor.getSession().then(function(multiFactorSession) {
  // Specify the phone number and pass the MFA session.
  var phoneInfoOptions = {
    phoneNumber: phoneNumber,
    session: multiFactorSession
  };
  var phoneAuthProvider = new firebase.auth.PhoneAuthProvider();
  // Send SMS verification code.
  return phoneAuthProvider.verifyPhoneNumber(
      phoneInfoOptions, recaptchaVerifier);
})
.then(function(verificationId) {
  // Ask user for the verification code.
  var cred = firebase.auth.PhoneAuthProvider.credential(verificationId, verificationCode);
  var multiFactorAssertion = firebase.auth.PhoneMultiFactorGenerator.assertion(cred);
  // Complete enrollment.
  return user.multiFactor.enroll(multiFactorAssertion, mfaDisplayName);
});
Related