Query lab 40 bonus XP

Find the admins who are actually exposed

Objectives

Your CISO wants "a list of admins without MFA" for tomorrow's risk committee. The identity team says the number is zero, because their dashboard counts anyone with any factor enrolled.

SMS is a factor, but it is not a factor the policy accepts for administrative access, and deactivated accounts should not inflate the finding. Write a query over the `users` table returning the email of every ACTIVE admin whose MFA factor is not one of the accepted strong factors.

Table: users

email                | role   | status   | mfa_factor
---------------------+--------+----------+-----------
ada@corp.example     | admin  | active   | webauthn
brs@corp.example     | admin  | active   | sms
cyn@corp.example     | admin  | active   | none
dev@corp.example     | admin  | disabled | none
eli@corp.example     | member | active   | none
fai@corp.example     | admin  | active   | totp
gus@corp.example     | admin  | active   | sms

Policy: strong factors for admin access are
webauthn and totp. Anything else is a gap.

Checks the server runs (5)

  • Query parses and returns an email column
  • Only administrator accounts
  • Deactivated accounts excluded
  • SMS counted as a gap, not as MFA
  • Result set matches the true exposure exactly

Check names are all you see here: the expectations that decide pass or fail, and the reference solution, stay on the server.

Step-by-step hints

The guided walkthrough, in full. It is free: no XP cost, and it does not touch the paid hint ladder or the reveal gate.

  1. Step 1

    Re-read the brief and name the trap

    The identity dashboard reports zero because it asks "has any factor?". The policy asks "has an accepted factor?". Those are different questions over the same table.

    Whenever a compliance metric looks impossibly good, suspect that the query encodes the schema rather than the policy.

  2. Step 2

    Read the fixture row by row

    Walk the seven rows and decide, for each, whether it belongs in the finding: before writing any SQL. Note the row that is an admin but not active, and the row that is active but not an admin.

    The last two lines of the fixture state the policy. They are the only definition of "strong" that matters here.

  3. Step 3

    Read the starter

    The starter selects the right column from the right table and filters on exactly one condition. Your work is entirely in the WHERE clause.

  4. Step 4

    Scope: role and status

    Two of the three conditions are about who is in scope at all. Ask: does my result include anyone whose account cannot be used, or anyone who is not an administrator?

    A disabled account in the finding inflates the number and gets the whole report challenged.

    Only administrator accountsDeactivated accounts excluded

  5. Step 5

    Encode the policy, not the schema

    The third condition is the policy. Rather than enumerating every unacceptable factor, a list that grows silently as the identity provider adds features, express the condition as "not one of the accepted values".

    That form fails safe: a new factor type is a gap until someone decides it is not.

    SMS counted as a gap, not as MFA

  6. Step 6

    Check your row count before you run

    From your read of the fixture you should already know how many rows the correct query returns and which emails they are. If the runner disagrees, one of your three conditions is doing more or less than you think.

    Query parses and returns an email columnResult set matches the true exposure exactly

  7. Step 7

    Run and read the failures

    The exact-match check is the strict one. If everything else passes but it fails, you are off by one row, usually the disabled admin or a factor value you accepted by accident.

Rules summary

  • XP on pass

    40 bonus XP the first time every check goes green.

  • Paid hints

    2 available. Each costs 25% of the lab XP (about 10 XP).

  • Reveal solution

    Scores 0 XP and unlocks only after 3 check runs.

  • Attempt cap

    60 check runs per learner. The runner warns you in the last 10.

  • Drafts

    Your editor content is saved in this browser, so a reload will not lose work.

  • Walkthrough

    Always free and never penalised: use it before spending a hint.