# Verify risk scoring, in log mode

> Every browser challenge and Verify widget check gets a 0–100 risk score from what the request already carries; log only by default. Security events now carry the client's ASN.

The [browser challenge](https://developers.openwaf.dev/waf/browser-challenge/), [under attack mode](https://developers.openwaf.dev/waf/under-attack/) and the [Verify widget](https://developers.openwaf.dev/waf/verify-widget/) now give each challenge a [risk score](https://developers.openwaf.dev/waf/verify-risk/) from 0 to 100. The score comes from signals the request already carries: a hosting or datacenter network, the threat feeds and the address's reputation, recent challenge volume, failures and replays from the same network or ASN, a TLS ClientHello or low-entropy headers that contradict the claimed browser, automation User-Agents, `navigator.webdriver`, and a proof of work solved faster than a browser can or always in the same time. No canvas, WebGL, audio or font fingerprints, no high-entropy client hints and no third parties.

The score picks a level: `pass`, `harder` (up to 3 more bits of proof of work), `interactive` (the one-click step) or `block` (`403`). Each zone sets the mode and thresholds in `challenge.risk`: **log** by default, which counts the levels and **applies nothing**, with thresholds 30, 60 and 90. Leave it in log, read the risk section of the Verification analytics (dashboard, `openwaf-cloud ctl challenge report` or the MCP tool `challenge_report`), and switch to `enforce` when the split looks right: in **Security → Verification → Risk scoring**, `PATCH …/edge` with `{"challenge": {"risk": {"mode": "enforce"}}}`, `openwaf-cloud ctl zones set example.com challenge.risk.mode=enforce` or the MCP tool `update_settings`.

Risk scoring raises the cost of automation; it doesn't prove that a visitor is human, and a real browser driven from residential addresses can still pass. See the [limits](https://developers.openwaf.dev/waf/verify-risk/#limits).

Also fixed: the `asn` of [security events](https://developers.openwaf.dev/analytics/security-events/) and of the AI Crawl Control analytics was always `0`; it now carries the client's network.
