mrkeyoor.com_
Tue 01 Sept 17:45 UTC
Open Source6 min read

Anti-Mage Hit 563 Stars by Scoring Browser Contradictions

The new Go project checks whether a browser's reported traits agree, while trying to avoid punishing missing features or exposing a tuning guide.

A GitHub repository created on August 22 had already reached 563 stars when MrKeyoor's brief captured it. The interesting number inside Anti-Mage, though, is zero: a zero score only means the scanner found no disagreement in the evidence it could read. It does not certify that a browser is ordinary, private, or untouched. That restraint gives this small MIT-licensed project a sharper purpose than the usual browser fingerprinting demo. Anti-Mage tries to score contradictions inside a browser environment without claiming to identify the product or person behind them.

The project runs as a local Go server with an embedded web page. A browser fetches a scan configuration, measures its own exposed surfaces, then sends the observations back for assessment. The result contains one of five determinations, from coherent to instrumented, plus a score from 0 to 100 in steps of ten. The README's API contract is deliberately narrow: the response echoes the supplied observation IDs, but does not reveal which individual reading changed the score.

That distinction matters because browser traits have two very different uses. The W3C defines browser fingerprinting as identifying or re-identifying a user, agent, or device through observable characteristics, and notes that the same machinery can support security checks or tracking. Its fingerprinting guidance lists window size, fonts, devices, performance and graphical output among active signals. Anti-Mage samples some of those surfaces, but combines them to ask whether they describe one coherent machine.

Contradictions carry more weight than missing data

Anti-Mage's central rule is asymmetric. If a capability appeared in a browser release later than the version the environment claims to run, its presence can count as disagreeing evidence. If an expected capability is absent, the scanner abstains because policy, platform support, build options or disabled features can explain the gap. The project's engine-feature table currently records features from Chrome 150 and 151, and marks each row as verified or unverified based on an observed system.

The same pattern appears in simpler checks. A viewport cannot be larger than the screen it says contains it when both values use the same CSS-pixel scale, so that arithmetic can expose a contradiction. A window with a negative coordinate may sit on another display whose size the scanner cannot see, so Anti-Mage declines to judge it. The project documentation describes these exit paths as part of the result, rather than treating every unusual value as suspicious.

Graphics checks are similarly conditional. Anti-Mage compares what WebGL says about a graphics device with whether WebGPU can obtain a hardware adapter. It only raises the score by one step when those interfaces disagree because driver support or browser policy can create the same state on an honest machine. Its AV1 decoder table goes further: four Nvidia generations are documented, but only the RTX 30-series row is marked verified with a specific observed Windows 10 and Chrome 151 configuration. The other rows remain unusable as scoring evidence until someone observes them.

This is an unusual choice for a repository chasing a hard problem. Many detection systems benefit from claiming broader coverage. Anti-Mage exposes the gaps instead. Its reference records carry a source, a checked date and a Verified flag, and the assessment code refuses to treat unverified rows as evidence. The reference package applies that structure to engine features, Windows fonts, native JavaScript shapes and GPU decoding data.

The scanner withholds its own answer sheet

An integrity scanner can become a repair manual for the environment it is trying to inspect. Anti-Mage reduces that risk by counting independent bodies of evidence, quantising the result and returning no per-reading verdict. A caller sees the overall determination and the supplied observation names. It does not receive a line saying that a particular font, accessor or timing result caused the increase. That behavior is defined in the public assess package, while the individual scan rules sit behind an internal package boundary.

The server also owns the questions and clock for a scan. GET /api/bootstrap issues a nonce and selected inputs; POST /api/scan resolves that nonce and evaluates the browser's observations against the server-held values. The implementation caps a request body at one megabyte, applies 30-second read and write timeouts, sets Cache-Control: no-store, and refuses to listen on a non-loopback address. Its default use therefore keeps the page and assessment service on the machine being tested.

The loopback restriction arrived after the project found a concrete mistake in its own server. An empty host value could pass an earlier check and bind the scanner to every network interface. A commit on August 26 changed the code to reject that form and recheck the listener's resolved address. The same patch moved time-zone probes into the past, since comparing future offsets can produce false disagreements when jurisdictions change their rules.

Those corrections are useful evidence about the maturity level. The repository contains extensive Go test files, but it has no tagged release, package registry instructions or published compatibility matrix. Its module declares Go 1.24 and no external dependencies. The documented local path is short:

 git clone https://github.com/N4darae/anti-mage
 cd anti-mage
 go run .

The command starts a loopback service and prints the URL to open. The build instructions say make check runs formatting, vetting and the test suite. MrKeyoor inspected the source but could not independently execute those tests in the reporting environment because a Go toolchain was not installed, so the repository's clean-test claim remains maintainer-reported here.

A score that cannot identify its cause still has privacy costs

Anti-Mage says it does not collect experiment data and its local server returns a compact assessment, but the browser page still performs active measurements. The W3C warns that active fingerprinting can combine window dimensions, installed fonts, graphics behavior and other attributes, often sending the characteristics to a server for combination. The guidance also says active collection may be detectable on the client, while server-side combination can be harder to evaluate. Deployers who lift Anti-Mage's collector into a remote service would change the privacy boundary established by its loopback-only default.

The project also refuses to infer intent. Privacy tools, accessibility software and content blockers can modify many of the same browser surfaces as automation or evasion tools. Anti-Mage's stated ceiling is that an environment appears modified; it does not name a vendor, tool or person as the cause. A policy that treats instrumented as proof of fraud would therefore claim more than the scanner does.

There is another practical limit: verified reference data is narrow. The GPU decoder check has one observed generation, the engine-capability table focuses on a small set of very recent Chrome features, and some readings intentionally record observations without affecting the score. That makes the current code easier to audit, but it also means a coherent result can come from limited coverage. The determination insufficient exists to separate too little evidence from evidence that agrees, according to the assessment API.

What developers can take from it

Anti-Mage is most useful today as an inspectable scoring design. The portable idea is its abstention model: a missing signal does not automatically count against the browser, one cause should not be counted twice, and a reference value cannot become evidence merely because documentation says it should be true. A recent correction fixed three paths where an inconclusive reading still entered the denominator, lowering confidence for ordinary configurations. The tests had encoded the same mistake in two cases.

That history makes the 563-star burst understandable. Browser integrity work usually hides the scoring model, which makes false-positive analysis difficult. Anti-Mage publishes the collector, evaluator, provenance tables and corrections under MIT terms. It still withholds a granular answer sheet from runtime callers, preserving some resistance to easy tuning while leaving the implementation open for review. The repository had 355 Go test and example functions when inspected, although function count says nothing about whether its reference population is broad enough.

Watch the reference tables and release process next. More observed browser, operating-system and GPU combinations would strengthen the project's claims only if its strict abstention rules survive the expansion. A tagged release and repeatable compatibility results would also make adoption easier to judge. Until then, Anti-Mage is a promising, early implementation of a narrow claim: it can find some browser contradictions, and it is unusually explicit about the cases where it cannot.

We reviewed this

  1. browser — our honest review
  2. anti-mage — our honest review

Sources

  1. The Anti-Mage Project
  2. Anti-Mage loopback server implementation
  3. Anti-Mage engine feature reference table
  4. W3C Fingerprinting Guidance for Web Specification Authors
  5. Anti-Mage abstention correction