Test User Authentication
Configure how our agents sign in as your test users — passwords, emailed one-time codes, authenticator apps, and magic links
Almost everything worth testing sits behind a login. Before our agents can map your authenticated surface — the dashboards, the account settings, the admin pages, the per-user data that authorization bugs live in — they have to sign in as a real user of your application.
This guide covers how to tell us what your sign-in actually requires, including applications that never ask for a password at all.
Declaring the wrong login method costs you a whole scan. If an application signs in with an emailed code but is configured with a password, our agents submit a password the app never asked for, the login fails, and the entire authenticated surface goes untested — while the report tells you to check a credential that was never wrong.
Step 1: Choose how each account signs in
In the Test Users step of the application wizard, each account has a login method. Pick the one that matches what a human sees when they sign in:
| Login method | What it means | Choose when |
|---|---|---|
| Password only | Email/username and a password. Nothing else. | Classic username + password login |
| One-time code only | No password — a magic link or emailed code is the sign-in | Passwordless / "magic link" / "email me a code" apps |
| Password + one-time code | Password first, then a second-factor code | Password login protected by 2FA |
If you pick either option involving a code, you will then be asked "Where do we get the code?"
Step 2: Tell us where the code comes from
| Source | How it works | Best for |
|---|---|---|
| Email it to us | We generate a mailbox address and fill it in as this account's email | Emailed codes and magic links |
| Authenticator app | You paste the TOTP secret from your 2FA enrolment screen | Google Authenticator, Authy, 1Password |
| Fixed test code | Your environment accepts a constant instead of a real code | Staging environments with a bypass code |
Each is described below. You only need one per account.
Email it to us (scanner mailbox)
Best for passwordless apps, emailed one-time codes, and magic links.
Select "Email it to us"
We immediately generate a dedicated address ending in @otp.modernpentest.com
and fill it into the account's Email field. It is unique to that account.
Create the account in your application with that exact address
This is the step people miss. The address only receives codes if your application is actually sending them there — so the test user in your app must have the generated address as its email.
Copy the address out of the form and either register a new test account with it, or change an existing test account's email to it.
Verify a message arrives
Open the application's detail page after saving. The verification-code card shows whether we have ever received mail at that address, and a Test inbound button sends a probe to confirm delivery is working end to end.
Until your application sends its first message, the card warns "no message from your app yet — is this set as the test user's email?" — which is the tell that step 2 was skipped.
Magic links work too. If the message contains a sign-in link rather than a numeric code, we follow it. For safety, we only follow links that are HTTPS and that point within the scope you configured for the application — a link to any other domain is ignored rather than followed.
We extract the code or the sign-in link and store only that. The message itself is not retained — one-time-code emails from a real application are often PHI- or PII-adjacent, and so are their subject lines.
Authenticator app (TOTP)
Best for accounts protected by Google Authenticator, Authy, 1Password, or any standard TOTP app.
When you enrol a test account in two-factor authentication, the enrolment screen
shows a QR code and — usually behind a link like "Can't scan the code?" — the
same secret as text. Paste that text secret into the Authenticator secret
field. A full otpauth:// URI works as well; we read the parameters out of it.
We support the standard TOTP parameters: SHA1, SHA256 and SHA512, 6 or 8 digit codes, and custom periods. Google Authenticator's defaults are our defaults, so in most cases you can paste the secret and change nothing.
Counter-based HOTP (otpauth://hotp/...) is not supported — it has no
time-based equivalent and each code consumes a counter your app also tracks.
The secret is encrypted before it is written down and is never sent to an agent. Agents ask our backend for a code at the moment they need one and receive only six digits back.
Fixed test code
Some staging environments accept a constant — 000000, say — in place of a real
one-time code. If yours does, this is the simplest option. The code must be
4 to 10 digits.
A fixed code is a standing MFA bypass. If the application is marked as a production environment, we refuse to store one unless you explicitly acknowledge that, and the wizard will not let you add the user until you do. On a production application, prefer an authenticator secret or a scanner mailbox.
When the username is not the email
Some applications want a username at the login form but send codes to an email address. The Username field is optional and exists for exactly this case: fill in both, and we submit the username at the form while expecting codes at the email.
This also matters for the scanner mailbox. Selecting Email it to us replaces the account's email with the generated address — if your login form takes a username, put it in the username field so it survives.
Verifying before you scan
Every configured account gets a card on the application's detail page showing the method in use and whether it has been verified. Use it before your first authenticated scan rather than after:
- Mailbox — click Test inbound, and confirm the card reports a received message. A green result proves DNS, delivery and parsing all work.
- Authenticator app — the card can generate a current code so you can compare it against your own authenticator app. If they match, the secret is correct.
Troubleshooting
| Symptom in your report | Usual cause | Fix |
|---|---|---|
credentials_rejected before any code screen | The login method says password, but the app is passwordless — or the account's email was changed without updating it in your app | Re-check the login method, and confirm the mailbox address is the account's email in your app |
| Card says "no message from your app yet" | Your application has never sent to the generated address | Set the generated address as the test user's email in your application |
| Test inbound succeeds but real codes never arrive | Your app sends from a domain we reject, or to a different address than the one shown | Confirm the exact address on the card matches the account in your app |
otp_rejected on an account you know is configured correctly | The code expired before it was submitted, or was consumed by a parallel check | Usually transient; if it repeats on every scan, contact support |
| Saved user reads "One-time code (not set)" | A code source was never saved for that account | Open the application's detail page and configure the source on that user's card |
We deliberately cap how many codes we request per account during a scan. If a code source is misconfigured, you get a small number of messages and a clear diagnostic — not a real person's inbox filled with sign-in codes.
What we store
| Item | How it is handled |
|---|---|
| Authenticator secrets and fixed codes | Encrypted at rest; never sent to an agent |
| Generated mailbox addresses | Stored in plain text — they are addresses, not secrets |
| Received messages | Not retained; we keep only the extracted code or sign-in link |
| Codes in logs and reports | Redacted |
Use dedicated test accounts with realistic permissions. Never configure a real user's account, a production admin, or a personal authenticator secret.
Next Steps
- Adding Applications — the full wizard walkthrough
- Run your first pentest
- Reconnaissance — how the authenticated surface gets mapped
- WAF Bypass Configuration — if agents cannot reach the login page at all
Last updated: September 2, 2026