Reduce Noise when Analyzing User MFA Status with Graph Queries

circle
circle

There is no doubt multi-factor authentication (MFA) is a simple and effective way to reduce account compromise, yet only 11% of all enterprise accounts use a MFA solution overall, accordingly to latest data from Microsoft.

Are there users without MFA enabled?

That’s a question our security team wants answered and alerted. In our internal JupiterOne account, we have an audit/alert rule configured to check for user accounts without MFA enabled. The J1QL query for that particular rule is written as such:

Find User with mfaEnabled != true 
  that !(ASSIGNED|USES|HAS) mfa_device

This checks for any user that does not have the

mfaEnabled

attribute directly on the user entity and does not have a relationship (assigned/has/uses) to an MFA device entity.

Hmm… so many false positives because of SSO

However, this query by itself has false positives in an environment with Single Sign On (SSO) configured.

For example, our users in Bitbucket, Jira, KnowBe4, and many other apps authenticate via Okta SSO. The users within these app accounts do not have MFA directly configured, and do not have an MFA device directly associated, because users never authenticate directly.

To accurately determine whether any user in these accounts does or does not use MFA for authentication, we will have to correlate them to SSO users and applications configured in Okta. For each user in an account connected via SSO, we have to check the following:

  1. An application is configured in Okta that connects it to the corresponding account
  2. A user from the target account has a matching active SSO user assigned to the SSO application in Okta
  3. The matching active user in Okta has MFA configured/assigned

This configuration scenario can be seen in the following graph, showing my Bitbucket user does not have MFA configured but it is actually authenticating via a connected Okta application, and my Okta user does have a number of MFA devices configured:

We need an automated way to “enrich” my Bitbucket user in the above example so that it is not included in the “user accounts without MFA enabled” alert rule. Here’s how we make this work.

Reduce false positives using results from graph queries

First, we can use the following query to check for #1 and #2:

Find User with _key='<unique_key_of_the_user_entity>' as userA
  that has Account
  that connects okta_application
  that assigned okta_user with active=true as userB
where
  userA.name = userB.name or 
  userA.username = userB.username or
  userA.email = userB.email

Enrichment: if this query returns a match, we can set

ssoUser: true

on the originating user entity (i.e.

userA

, the provider app user).

If your primary SSO provider is not Okta, replace

okta_application

and

okta_user

in the query above (and below) with the appropriate ones.

Next, we can use a second query to check for condition #3:

Find User with _key='<unique_key>' and ssoUser=true as userA
  that has Account
  that connects okta_application
  that assigned okta_user with active=true as userB
  that (assigned|has|uses) mfa_device
where
  userA.name = userB.name or 
  userA.username = userB.username or
  userA.email = userB.email

Enrichment: if this query returns a match, we can set

mfaEnabled: true

on the originating user entity (i.e.

userA

, the provider app user).

You may notice this second query is very similar to the first one. It has an additional relationship traversal at the end:

that (assigned|has|uses) mfa_device

So why not do this in one query? The reason is the additional filter at the beginning:

and ssoUser=true

This filter is added to ensure we only set the

mfaEnabled

property on user entities that were identified as SSO users in the previous step.

Graph enrichment FTW!

Here’s my Bitbucket user after the enrichment is complete:

Now we repeat these two steps on each user that is not an Okta user (or whichever is your primary SSO provider — OneLogin, JumpCloud, etc.). This allows us to use our original “user accounts without MFA enabled” alert rule with all false positives virtually eliminated!

Review of the results validated that system accounts did not get the

ssoUser 
or

mfaEnabled 
flag, as intended, and identified a handful of users needing remediation.

Check out the entire code here.

avatar

Posted By Erkang Zheng

I envision a world where decisions are made on facts, not fear; teams are fulfilled, not frustrated; breaches are improbable, not inevitable. Security is a basic right. I am a cybersecurity practitioner and founder with 20+ years across IAM, pen testing, IR, data, app, and cloud security. An engineer by trade, entrepreneur at heart, I am passionate about technology and solving real-world challenges. Former CISO, security leader at IBM and Fidelity Investments. I hold five patents and multiple industry certifications. I am building a cloud-native software platform at JupiterOne to deliver knowledge, transparency and confidence to every digital operation in every organization, large or small.

To hear more from Erkang, get our newsletter. No spam, just the good stuff once or twice a month. Sign up below.

PREVIOUS ARTICLE

cyber-security 1

Ad Title Placeholder

Lorem ipsum dolor sit amet, consectetur adipiscing elit.