hCaptcha
hCaptcha is a proprietary device fingerprinting and CAPTCHA platform as a service with applications for bot detection. Wikimedia Foundation is using this service for all account creations, edits made using most editing interfaces, and for repeated failed login attempts on some wikis. Users with the skipcaptcha right (autoconfirmed users) are exempted and do not see hCaptcha.
Wikimedia uses hCaptcha Enterprise's First-Party feature, which routes all client traffic through a Wikimedia controlled proxy.
Design
The basic idea is the same as the standard hCaptcha flow. However, to minimize impact on user privacy, user requests do not go directly to hCaptcha servers, but are sent through our proxy, which strips IP addressess, cookies and other identifying information.
Client Side
We use hCaptcha for most editing interfaces and for all account creations. This involves loading code and assets using the hCaptcha reverse proxy, and displaying the hCaptcha widget, and then executing hCaptcha when a user submits the form.
Loading hCaptcha
We load hCaptcha at different times depending on the interface that is used:
- For the desktop wikitext editor, the VisualEditor interface, Special:UserLogin, and Special:CreateAccount the hCaptcha JS is loaded when a user interacts with the form
- For the mobile wikitext source editor, the hCaptcha JS is loaded when the user opens the save changes step
Loading hCaptcha first loads the secure-api.js file and executes it. This JS file is self-hosted and is stored in the static directory. This causes several other requests to be made through the reverse proxy to fetch additional data and files.
Rendering and executing hCaptcha
When the hCaptcha JS is loaded, the hCaptcha widget can be rendered. On WMF wikis this is displayed in "invisible" mode, which means no visible checkbox for the user. The widget is rendered at different times depending on the form being used
When a user submits the form we halt the submission and execute hCaptcha. This usually makes several additional requests through the reverse proxy and may show a visual challenge to the user to complete. If successful, a token is passed back from hCaptcha that we append to the form submission that is validated by the server
Server side
Mediawiki
Server side CAPTCHA validation flow
MediaWiki handles hCaptcha in most situations like any other CAPTCHA. This means that classes like EditPage leave the hCaptcha specific checks to the hCaptcha code and get a pass/fail for the CAPTCHA. However, unlike question based CAPTCHAs a failure for the CAPTCHA is more likely due to request spoofing or an API request that did not show a user a hCaptcha challenge.
hCaptcha passes the token passed by the client in the request to the siteverify API which will return a success if the token is valid. If the token is valid then the user has passed the CAPTCHA. If this request fails or responds that the token is not valid, then the user does not pass the CAPTCHA.
In some situations MediaWiki may require a stricter check, which leads the server to respond with a CAPTCHA failure but with the stricter sitekey to be used. This currently is used to enforce that a user sees a visual challenge when configured by the community through an AbuseFilter.
FancyCaptcha fallback mechanism
MediaWiki keeps an eye on the hCaptcha and will failover to use FancyCaptcha (the CAPTCHA in place before hCaptcha is enabled on a wiki). This happens if more than 5 requests in the last minute to the siteverify API have either failed with a HTTP error or returned invalid JSON
hcaptcha-proxy

- Forwards requests to hCaptcha
- Strips any identifying information by unsetting various headers
- Hashes client IP address,
<%= @nginx_ipblinding_conf %>blocks in NginX-'s (see below)
CDN → Load Balancer→ reverse proxy → hcaptcha upstream ("the internet")
- proxoid.discovery.wmnet (active/active service)
- The reverse proxy is a basic nginx installation Currently (Sept 2025) the proxy is installed on the
url_downloaderhosts.
Configuration
On https://dashboard.hcaptcha.com, we have several sitekeys defined for production wikis. Each sitekey is used by different actions and interfaces as configured in operations/mediawiki-config.
The sitekeys all share a secret key, which is defined in:
PrivateSettings.phpon the deployment hosts- Puppet private configuration for the hCaptcha reverse proxy.
mediawiki-config
There are toggles in wmf-config/InitialiseSettings.php that define wiki has hCaptcha functionality enabled or disabled. Changing these toggles will enable/disable hCaptcha as required, where a wiki without hCaptcha will use FancyCaptcha instead:
wmgEnableHCaptchacontrols whether hCaptcha is enabled at all on a wikiwmgEnableHCaptchaEditingcontrols whether hCaptcha is enabled for editing via the desktop wikitext editorwgHCaptchaEnabledInMobileFrontendcontrols whether hCaptcha is enabled for edits made via the mobile source editorwmgEnableHCaptchaAccountCreationAPIcontrols whether hCaptcha is enabled for the account creation APIwmgEnableHCaptchaForBadLogincontrols whether hCaptcha is enabled for repeated failed login attemptswmgEnableHCaptchaUploadWizardcontrols whether hCaptcha is enabled for the file upload wizard
Here is an example patch to do this: I80886c
Puppet
- modules/profile/manifests/hcaptcha/proxy.pp
- modules/profile/templates/hcaptcha/nginx.conf.erb
- modules/profile/templates/hcaptcha/proxy.nginx.conf.erb
- modules/profile/templates/hcaptcha/subdomain.nginx.conf.erb
- modules/role/manifests/hcaptcha/proxy.pp
- hieradata/common/profile/hcaptcha/proxy.yaml
- Puppet private IP blinding configuration
- Puppet private configuration for the hCaptcha reverse proxy
Cookies
The proxy removes all cookies except hmt_id, per Idb012f and I87190f.
Monitoring
Runbook
Depooling an hcaptcha-proxy instance / an instance is down
Completely disable hCaptcha
In case of emergency, disable this functionality by toggling wmgEnableHCaptcha in wmf-config/InitialiseSettings.php to false for the wikis to disable hCaptcha on (or default if everywhere).
Here is an example patch to do this: I80886c
Enable emergency CAPTCHA
If all edits should encounter a visual challenge (otherwise known as emergency CAPTCHA), then log into the hCaptcha dashboard and change the relevant sitekeys to "always challenge" mode.
Note that in cases of bot attack, hCaptcha will likely adapt the rate of visual challenges in the normal 99.9% mode (so this should not be done unless necessary)
Proxy smoke test
Contact information
The hCaptcha integration with on-wiki workflows is managed by the Product Safety and Integrity team as part of the WE4.2 and WE4.10 anti-abuse signals hCaptcha project.
The proxy infrastructure is managed by Traffic SRE.