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.
- 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.
- 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.
- 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.
- 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
- 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
- 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
- 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.