Headless browsers and automation detection: telling a script from a person.
Headless browser detection and browser automation detection explained: what automated traffic looks like, what can be reported, where the limits are.

Headless browser detection is the practice of working out whether a real browser is being driven by a program instead of a person. A headless browser is an ordinary browser engine running without a visible window, controlled by code, and it is behind most automated traffic on the modern web, from useful monitoring to scraping and credential stuffing.
This explainer covers what automation is, why it is hard to hide completely, what Fingerly reports about it, and how to act on the answer without blocking the people and tools you want.
What is a headless browser?
It is a browser without the screen. Instead of a person clicking, a script tells the browser to load pages, fill forms and press buttons, and it can do so thousands of times faster than a human. Developers rely on this for testing, uptime monitoring and generating previews, so headless is not evil in itself.
The trouble starts when the same technique is used to impersonate customers. Because a driven browser executes your JavaScript, renders your pages and keeps cookies like any visitor, simple bot protection that looks for missing features no longer works. The traffic arrives as a real browser, which is exactly why detection has to look at the browser itself.
Why is automated traffic a problem for your business?
Scripted traffic rarely wants what your product is for. It wants what your product holds.
- Credential stuffing against logins, using leaked password lists.
- Fake signups and spam accounts, created in bulk for bonuses, trials and referral rewards.
- Content scraping of prices, listings and member data, which hands your work to anyone who asks for it.
- Inventory hoarding and scalping at checkout, where a script outruns every customer.
- Invalid traffic and fake traffic that inflate analytics and waste advertising and email budgets.
- Form abuse: spam submissions, SMS pumping on one-time passcodes, and card testing at checkout.
How does browser automation detection work?
It looks for evidence that a browser is driven rather than used, and for evidence that someone tried to hide it. Fingerly runs this on every identification of a web visitor and reports what it finds, with a confidence, so your server can weigh it.
The findings fall into groups you can read and weight separately. Browsers driven by automation frameworks are reported as automation. Clients that identify themselves as a bot, crawler or scripted tool are reported as declared bots. Browsers running inside virtual machines are reported as such, since a real customer on a real device rarely is. And because serious automation removes its obvious flags, browsers whose built-in behaviour has been modified are reported as tampering, alongside the automation they disguise.
There is also a quieter finding. A report that gives away too little to identify anyone is flagged as suppressed, and a device that is far busier than your own traffic normally is, learned for your own organisation, environment and platform, is flagged as high activity. Every finding has a default weight that you can change, and the weights sum into a suspect score with a level of low, medium or high.
Can automation hide from detection?
It can try, and the honest answer is that no automation detection is perfect. Stealth tooling exists to remove the flags that give a driven browser away, and the contest between hiders and detectors never ends. What hiding cannot easily do is remove the evidence of having hidden: a browser that has been modified to look ordinary behaves a little differently from one that never needed to be.
That is why Fingerly reports tampering and automation together rather than treating them as separate questions, and why you should treat the output as evidence, not proof. A clean result from a patient attacker driving a real browser at human speed is possible. A weighted score, combined with your own limits per device, still raises the cost of every extra account or login attempt.
How do you stay accurate about humans versus bots?
Human vs bot is not a binary, and treating it as one causes the worst mistakes. A person can use a browser extension or a hardened privacy setup. A company can run an office full of staff behind one address. Your own testing and monitoring tools are bots you want. Fingerly keeps privacy-minded settings and incognito windows out of the verdict by default, or at low weight, because caring about privacy is not evidence of fraud.
Declared crawlers are a related case. A client that says it is a bot has been honest, so you can choose to allow it on public pages and refuse it on forms. Decide per action, not per visitor.
How do you add bot detection to a form or checkout?
Identify when the form is submitted, check on your server, and answer in proportion. The same five steps cover bot detection for signups, logins, checkout and any other form.
- Identify on submit with the browser SDK, tagged with the action, such as checkout or contact. If identification fails, carry on and send no request ID.
- Send the request ID with the form fields to your backend.
- Read the stored event with a secret key, and check that it exists, matches the tag, is recent and has not been used.
- Read the triggers and the level. For an automation finding, ask for a second step or refuse; for a medium level, add friction a person can pass.
- Keep your own tools out of the way: run your test suites and monitors against development keys, and give production tooling a path you control.
Because Fingerly never asks anything of the visitor, there is no puzzle to solve and no prompt to dismiss. That makes it an invisible bot detection layer: your application chooses whether a challenge appears at all. To keep detection working behind ad blockers, serve the SDK and its requests from your own domain with a first-party proxy.
What should you do with a bot verdict?
Do not hand it a clear error. A visible refusal tells an attacker which signal fired, and they will adjust. Better responses are quiet ones: accept the request and drop it, return the same generic failure you use for any bad input, delay the response, serve cached or reduced data to a suspected scraper, or hold the resulting account for review.
For scraping, which is the hardest case because the requests are individually harmless, add a limit per visitor ID and read automation findings on the data endpoints you care about. For checkout, the stakes justify a second factor or a payment verification step on a medium level.
