All articles Integration

Protecting a Login Form With Device Signals

The login form is the single most attacked surface most applications own. It is where credential-stuffing bots test stolen password lists, where account takeover plays out, and where the trade-off between security and friction is most painful. Add too much friction and real users abandon; add too little and attackers walk in with valid credentials they bought for pennies.

Device signals resolve that tension by moving the question from “is this password correct” to “is this the person and device we expect.” A correct password from a brand-new device in a new country, arriving faster than a human could type, should not be treated the same as the same password from a device that has logged in reliably for a year. This guide shows how to protect a login form with device intelligence, step by step.

What device signals add to authentication

Passwords authenticate a secret; device signals authenticate a context. Together they turn a binary allow/deny into a risk decision.

  • Stable visitor ID. Recognise returning devices even without a cookie, so a familiar device becomes a trust signal and an unfamiliar one a caution. See new device login detection.
  • Smart Signals. Flags for bot, VPN, Tor, datacenter IP, and tampering surface the infrastructure attackers rely on.
  • Behavioral biometrics. Typing and pointer cadence distinguish a human from an automated submitter, covered in behavioral biometrics explained.
  • Velocity across accounts. One device attempting many usernames is the signature of credential stuffing.

Combined into a confidence score and a suspect score, these let you keep the happy path frictionless while concentrating scrutiny where it belongs.

Designing the risk decision

The goal is a tiered response, not a wall. Map score ranges to actions so that most logins are untouched and only genuine risk escalates.

Risk levelSignalsResponse
LowKnown device, clean IP, human cadenceAllow, no friction
MediumNew device, otherwise cleanAllow with step-up (MFA / email verify)
HighBot flag, datacenter IP, credential-stuffing velocityBlock or hard challenge
CriticalKnown-bad device from reputation networkBlock and alert

The design principle is that friction should be proportional to risk. A returning customer should almost never see a challenge; a headless browser hammering the endpoint from a datacenter range should never see the account. This is the essence of risk-based authentication, and it is why device signals reduce aggregate friction even as they raise security.

Step-by-step integration

The integration has three moving parts: collect on the client, verify on the server, decide before authenticating. The critical rule is that the client is untrusted, so the verdict must be re-verified server-side.

Client-side, load the agent and attach the result to the login request:

import { Prynt } from '@prynt/js';

const prynt = await Prynt.load({ endpoint: '/prynt' });

loginForm.addEventListener('submit', async (e) => {
  const { sealedResult } = await prynt.get();
  // Send the sealed result alongside credentials
  hiddenField.value = sealedResult;
});

Server-side, unseal and verify before checking the password:

on POST /login:
  1. Verify and unseal the sealed result server-side (reject if invalid/expired).
  2. Read visitor_id, suspect_score, and smart signals.
  3. If suspect_score is high OR bot flag set -> block or challenge.
  4. Verify the password.
  5. If password ok AND device is new -> require step-up (MFA).
  6. If password ok AND device known-good -> issue session.

Verifying the sealed result server-side is non-negotiable: it is what stops an attacker from forging a “low risk” verdict from a browser they control. For deeper server patterns see node server-side verification and protecting a login form.

Handling the hard cases

The interesting engineering is in the edge cases, where naive implementations either lock out real users or wave attackers through.

  • Shared and family devices. Multiple legitimate users behind one visitor ID is normal. Treat device recognition as a trust boost, never as sole proof of identity.
  • Privacy-hardened browsers. A user on a privacy browser will look like a new device every time. Do not punish that with a hard block; use step-up instead so real users can still proceed.
  • First login ever. Every user is new once. New-device logic should escalate to verification, not denial, so onboarding is not broken.
  • Residential-proxy attacks. Sophisticated stuffing routes through residential IPs to look clean. Lean on device and behavioral signals plus residential proxy detection rather than IP reputation alone.

The through-line is graceful degradation: when a signal is ambiguous, escalate friction rather than deny outright, so security failures do not become customer-service failures. Watch reducing false positives for the tuning discipline this requires.

Measuring whether it works

Shipping the integration is the start; proving it helps is the job. Track a small set of metrics before and after.

  • Stuffing block rate. Share of automated login attempts stopped before authentication.
  • Step-up rate. Fraction of legitimate logins that hit a challenge; if it climbs, your thresholds are too tight.
  • ATO incidents. Confirmed takeovers per period, the outcome that ultimately matters.
  • False-positive rate. Legitimate users blocked or over-challenged, the cost side of the ledger.

These tie into the wider framework in bot detection metrics and KPIs. The right posture is to watch the step-up and false-positive rates as carefully as the block rate, because a login defense that annoys real users will be switched off.

Frequently asked questions

Does adding device signals to login add friction for real users?

No, when done right it removes friction. Recognised devices sail through, and only sessions that look risky see step-up challenges, so the median legitimate user experiences a faster, quieter login than a system that MFAs everyone.

Where should the device check happen, on the client or the server?

Collect signals on the client but always make the decision on the server. A client-side verdict can be bypassed by an attacker who controls the browser, so the server must verify the sealed result before trusting it.

What if a legitimate user always looks like a new device?

Privacy-hardened browsers wipe recognition each session, so treat “new device” as a trigger for step-up verification rather than a block. Real users complete a lightweight challenge; attackers still face the same barrier, and no one is locked out.

Protecting a login form with device signals is less about building a wall and more about spending scrutiny where risk actually is. Collect on the client, decide on the server, escalate proportionally, and measure both the attacks you stop and the users you inconvenience. Start from the SDKs and try the flow in the playground.

Run it yourself

Prynt is open-source, self-hostable device intelligence — visitor IDs, bot & fraud Smart Signals, and behavioral biometrics you own end to end.

Keep reading