var suggestions=document.getElementById("suggestions"),userinput=document.getElementById("userinput");document.addEventListener("keydown",inputFocus);function inputFocus(e){e.keyCode===191&&(e.preventDefault(),userinput.focus()),e.keyCode===27&&(userinput.blur(),suggestions.classList.add("d-none"))}document.addEventListener("click",function(e){var t=suggestions.contains(e.target);t||suggestions.classList.add("d-none")}),document.addEventListener("keydown",suggestionFocus);function suggestionFocus(e){const s=suggestions.querySelectorAll("a"),o=[...s],t=o.indexOf(document.activeElement);let n=0;e.keyCode===38?(e.preventDefault(),n=t>0?t-1:0,s[n].focus()):e.keyCode===40&&(e.preventDefault(),n=t+1mCaptcha can protect your website from DDoS attacks. In this guide we’ll explore how to install mCaptcha on your website. The end result will be something like this, on your website:

A registration form with mCaptcha widget installed

For the purpose of this demo, we will be using demo.mcaptcha.org, a demo instance running in @realaravinth’s bedroom(for this same reason, it shouldn’t be used for anything serious)

1. Create an account and sign into the mCaptcha dashboard

Head over to demo.mcaptcha.org and create an account. When ready, sign in.

2. Create new site key

A site key is how a new CAPTCHA is configured within mCaptcha. To create a new site key, click on “New Site” button in the dashboard.

mCaptcha dashboard with the 'new site key' button highlighted

There are two options to create a new site key, easy and advanced. We are going to use the easy mode in this tutorial. If you are interested in learning more about the advance mode, please see here.

Easy Mode

Easy mode asks a few basic statistics about your website and generates a configuration that should work for your website. Currently, easy mode is guided by assumptions on suitable difficulty factors to protect a website but it will be fine-tuned as mCaptcha sees more deployment.

Configuration generated by easy mode can be tweaked later using the advance mode, as you become more familiar with how mCaptcha works.

Fill the form and submit it.

mCaptcha dashboard with the 'new site key' form in easy mode, with details filled in

Submitting the form will take you to a page where site key configuration can be viewed. “View deployment” link will display CAPTCHA widget with the supplied configuration. Click on it and grab the widget link.

4. Install mCaptcha on your website

Integration support is available for some frontend JavaScript frameworks. To see full list of supported frameworks, please see here.

There are two options to use the integration library to integrate mCaptcha on your website:

  1. Serve the integration library yourself
  2. Use a CDN like unpkg.com

In this tutorial, we’ll be using the CDN.

Pasting the following snippet on the page, within the form that requires to be protected will load the mCaptcha widget with the configuration supplied. Be sure to replace Your {{paste your widget link}} with the link obtained from the previous step.

 1<div id="mcaptcha__widget-container"></div>
 2<script src="https://unpkg.com/@mcaptcha/vanilla-glue@0.1.0-alpha-2/dist/index.js"></script>
 3<script charset="utf-8">
 4  let config = {
 5    widgetLink: new URL(
 6      {{paste yout widget link}}
 7    ),
 8  };
 9  new mcaptchaGlue.default(config);
10</script>

A full example is available here.

5. Configure backend to authenticate CAPTCHA tokens

  1. Get access token from the user’s form submission payload. The access token will be associated with a parameter called mcaptcha__token.

    1 mcaptcha_token = request.form["mcaptcha__token"]
    
  2. Validate access token with mCaptcha instance

 1payload = {
 2    "token": mcaptcha_token,
 3    "key": mcaptcha_sitekey, # captcha site key
 4    # mCaptcha account secret; available in settings
 5    "secret": mcaptcha_account_secret,
 6}
 7resp = requests.post(
 8    "https://demo.mcaptha.org/api/v1/pow/siteverify", json=payload
 9)
10resp = resp.json()
  1. If access token is valid, allow access to protected resource or deny access.
1 if resp["valid"] == False:
2     return "invalid captcha", 400
3 else:
4     return allow_access_to_protected_resource(request.form)

Please see here for a complete Flask example and here for an Actix Web example.

Congratulations, mCaptcha is now integrated with your website!

`},{id:1,href:"/docs/webmasters/configuring-difficulty-factor/",title:"Configuring Difficulty Factor",description:"mCaptcha has options to configure its proof of work engine behavior, this page explains how to determine difficulty facotrs that work best for your website!",content:`

mCaptcha is highly responsive to detecting DDoS attacks. Admins are advised to take advantage of it by setting low difficulty factors for normal traffic levels for their website.

Lowest advisable difficulty factor is 5000.

For instance, if it is normal for my website to get 2000 requests for every 30 seconds, I will set a cool down period of 30 seconds and the first level of difficulty configuration will have a visitor threshold of 2000 with a difficulty factor of 5000.

There are two modes to setting difficulty factor for your website on mCaptcha:

Easy option

Easy mode asks a few basic statistics about your website and generates a configuration that should work for your website. Currently, easy mode is guided by assumptions on suitable difficulty factors to protect a website but it will be fine-tuned as mCaptcha sees more deployment.

Configuration generated by easy mode can be tweaked later using the advance mode, as you become more familiar with how mCaptcha works.

new sitekey form in easy mode

Advance option

Advance mode gives the admin granular control over how mCaptcha behaves on their website. It has options to set the difficulty factor for each level of traffic(or visitor threshold, in mCaptcha speak), fully taking advantage of mCaptcha’s variable difficulty factor feature.

For instance, if it is normal for a website to get 200 requests over 30 seconds, then setting a very low difficulty factor for a visitor threshold of 200 and a cool down period of 30 seconds will allow the users to pass through without waiting on the CAPTCHA. But if 1000 requests over 30 seconds will bring down the service, then the admin can configure increasing levels of difficulty factor of increasing traffic levels, effectively rate limiting its users and protecting the underlying website.

new sitekey form in advance mode
`},{id:2,href:"/docs/self-hosting/getting-started/",title:"Getting started",description:"Get started with self-hosting mCaptcha",content:`

Get started

There are two main ways to self-host mCaptcha:

  1. Bare metal
  2. With Docker
`},{id:3,href:"/docs/self-hosting/bare-metal/",title:"Deploy bare metal",description:"Bare metal deployment is tedious, most of this will be automated with a script in the future.",content:`

2. Configure

mcaptcha is highly configurable.

Configuration is applied/merged in the following order:

  1. path to configuration file passed in via MCAPTCHA_CONFIG
  2. ./config/default.toml
  3. /etc/mcaptcha/config.toml
  4. environment variables.

1. Install postgres if you don’t have it already.

For Debian based distributions:

1sudo apt install postgres

2. Create new user for running mcaptcha

1$ sudo useradd -b /srv -m -s /usr/bin/zsh mcaptcha

3. Create new user in Postgres

1$ sudo -iu postgres # switch to \`postgres\` user
2$ psql
3postgres=#  CREATE USER mcaptcha WITH PASSWORD 'my super long password and yes you need single quote\`;
4$  createdb -O mcaptcha mcaptcha # create db 'mcaptcha' with 'mcaptcha' as owner

4. Install and load mCaptcha/cache module:

See mCaptcha/cache for more details.

4. Build mcaptcha

To build mcaptcha, you need the following dependencies:

  1. rust
  2. node(v14.16.0)
  3. yarn(JavaScript package manager)
  4. make

How to build

  1. Install Cargo using rustup with:
1$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
  1. Install node(v14.16.0)

  2. Install yarn(JavaScript package manager)

  3. Build with make:

1$ make dev-env && \\
2	make release

5. Install package:

1$ sudo cp ./target/release/mcaptcha /usr/bin/ && \\
2	mkdir sudo /etc/mcaptcha && \\
3	sudo cp config/default.toml /etc/mcaptcha/config.toml

6. Systemd service configuration:

  1. Copy the following to /etc/systemd/system/mcaptcha.service:
 1[Unit]
 2Description=mCaptcha: a CAPTCHA system that gives attackers a run for their money
 3
 4[Service]
 5Type=simple
 6User=mcaptcha
 7ExecStart=/usr/bin/mcaptcha
 8Restart=on-failure
 9RestartSec=1
10SuccessExitStatus=3 4
11RestartForceExitStatus=3 4
12SystemCallArchitectures=native
13MemoryDenyWriteExecute=true
14NoNewPrivileges=true
15Environment="RUST_LOG=info"
16
17[Unit]
18After=sound.target
19Wants=network-online.target
20Wants=network-online.target
21Requires=postgresql.service
22After=syslog.target
23
24[Install]
25WantedBy=multi-user.target
  1. Enable service:
1$ sudo systemctl daemon-reload && \\
2	sudo systemctl enable mcaptcha && \\ # Auto startup during boot
3	sudo systemctl start mcaptcha
4\`\`
`},{id:4,href:"/docs/self-hosting/docker/",title:"Using Docker",description:"Deploy mCaptcha using docker",content:`

With Docker

1. Configure

mcaptcha is highly configurable.

Configuration is applied/merged in the following order:

  1. path to configuration file passed in via MCAPTCHA_CONFIG
  2. ./config/default.toml
  3. /etc/mcaptcha/config.toml
  4. environment variables.

See CONFIGURATION.md for configurable options.

2. Run image

If you have already have a Postgres instance running, then:

1docker run -p <host-machine-port>:<port-in-configuration-file> \\
2	--add-host=database:<database-ip-addrss> \\
3	-e RUST_LOG=debug \\
4	-e DATABASE_URL="postgres://<db-user>:<db-password>@database:<db-port>/<db-name>" \\
5	mcaptcha/mcaptcha:latest

If you don’t have a Postgres instance running, you can either install one using a package manager or launch one with docker. A docker-compose configuration is available that will launch both a database instance mcaptcha instance.

With docker-compose

  1. Follow steps above to build docker image.

  2. Set database password docker-compose configuration.

  3. Launch network

1docker-compose up -d
`},{id:5,href:"/docs/self-hosting/dependencies/",title:"Database and cache",description:"mCaptcha server requires dependencies like a Postgres database and a Redis cache",content:`

Notes

Database

Redis

Instructions

Once again, there are two ways to go about this:

  1. Docker
  2. Bare metal

Docker

Database

Download and run Postgres

1docker create --name mcaptcha-postgres \\
2  -e POSTGRES_PASSWORD=<database-password> \\
3  -p 5432:5432 \\
4  postgres && docker start mcaptcha-postgres

Redis

1docker create --name mcaptcha-cache \\
2  -p 6379:6379 \\
3  mcaptcha/cache && docker start mcaptcha-cache

See mCaptcha/cache for more details.

1. Install Postgres if you don’t have it already.

For Debian based distributions:

1sudo apt install postgres

2. Create new user for running mCaptcha

1$ sudo useradd -b /srv -m -s /usr/bin/bash mcaptcha

3. Create new user in Postgres

1$ sudo -iu postgres # switch to \`postgres\` user
2$ psql
3postgres=#  CREATE USER mcaptcha WITH PASSWORD 'my super long password and yes you need single quote';
4$  createdb -O mcaptcha mcaptcha # create db 'mcaptcha' with 'mcaptcha' as owner

4. Install mCaptcha/cache

See mCaptcha/cache for more details.

`},{id:6,href:"/docs/help/troubleshooting/",title:"Troubleshooting",description:"Solutions to common problems.",content:`

Q: I just setup an instance but I am unable to login

mCaptcha by default is configured to server at localhost hostname. If the instance is deployed at another hostname, please try setting MCAPTCHA_SERVER_DOMAIN environment variable to the hostname at which your instance is deployed or setting the equivalent in config.toml:

1[server]
2domain=mydomain
`},{id:7,href:"/docs/api/browser/",title:"Browser libraries",description:"API documenttion for mCaptcha WASM library",content:`

The browser part of mCaptcha is divided into three components.

Glue code

This is the code that links mCaptcha with your website’s frontend code. It creates an iframe containing the mCaptcha widget and injects the received verification proof token into a hidden input field.

Support is available for various frameworks, see mCaptcha/glue for the full list.

For frameworks without official support, a low-level library, @mcaptcha/core-glue, can be used to implement support.

Widget Program

This part is served by the mCaptcha backend. It fetches PoW config from the backend, generates proof and submits it for verification. If verification is successful, it sends a message containing the verification proof token to the parent window, assuming it’s loaded as an iframe.

WebAssembly library which generates Proofs of Work for mCaptcha systems.

Proof-of-Work(PoW) library

WebAssembly bindings(mCaptcha/pow_wasm) are available for the main rust library(mCaptcha/pow_sha256).

For browsers without support WebAssembly, a polyfill(pow_sha256-polyfill) is available.

`},{id:8,href:"/docs/api/mcaptcha-system/",title:"mCaptcha System Library",description:"API documenttion for the core Library used in mCaptcha",content:`

Documentation for the library used in mCaptcha core.

Versions

`},{id:9,href:"/docs/api/pow-sha256/",title:"pow_sha256",description:"API documenttion for PoW Library used in mCaptcha",content:`

Rust crate which generates SHA256 Proofs of Work on serializable datatypes.

This is a fork of the pow library by @robkorn) with some new additions. Primary of these being:

Other small changes have also been included of various importance but mostly just stylistic/ease of use improvements.

Versions

Changelog

Changelog is available at the project’s repository

`},{id:10,href:"/docs/help/faq/",title:"FAQ",description:"Answers to frequently asked questions.",content:`

Coming soon

`},{id:11,href:"/docs/webmasters/terminology/",title:"Terminology",description:"Information about terminology used in mCaptcha, some of which unique to the project",content:`

Authorization token

When a visitor solves the CAPTCHA and sends their solution to an mCaptcha instance, the solution will be verified for correctness. If the solution is correct, mCaptcha will return a single use authorization token.

This authorization token should be attached to the visitor’s requited to the protected service and the protected service should validity of the authorization token with the mCaptcha instance and only allow authorization to protected resource if the authorization token is valid.

Cooldown Period

mCaptcha implements leaky bucket algorithm to measure current traffic levels. Cooldown period specifies the leak or the time after which a visitor addition is decremented.

For instance, if initial traffic level is 0 and a user visits one second later, the traffic level will be incremented to 1. Now, if the cooldown period is set to 30 seconds, the traffic level will be decremented after 30 seconds. So after 30 seconds, the traffic level will go from 1 to 0.

Difficulty Factor

Difficulty factor determines the time it takes to solve a CAPTCHA. The higher the difficulty factor, the longer it will take to generate a proof of work for it to solve the CAPTCHA.

mCaptcha’s proof of work based mechanism makes it highly accessible to people with special needs but it is important to choose the difficulty factor with care as very high difficulty factors will make the CAPTCHA inaccessible to users on slow devices.

Sitekey

Site key is a unique identifier associated with CAPTCHA configurations created on mCaptcha. It is required to integrate a CAPTCHA with your website.

Visitor Threshold

mCaptcha’s variable difficulty factor mechanism requires a website’s traffic statistics be split into levels, so that it can deploy the right difficulty factor for each level.

Visitor threshold is used to traffic into levels and mCaptcha accepts a difficulty configuration for each of these levels. When current traffic exceeds a difficulty factor, mCaptcha will increase the difficulty factor to the next configured level.

For instance, consider the configuration given below:

Level Difficulty Factor Visitor Threshold
1 5,000 2,000
2 50,000 5,000
3 500,000 10,000
4 5,000,000 15,000

If the website sees 2,000 requests in a 30 second window, level 1 difficulty factor(5,000) will be deployed. If the traffic increases to 5,000 requests in a 30 second window, then difficulty factor will be upgraded to level 2(50,000). Likewise 10,000 and 15,000 requests over 30 seconds will result in difficulty factor being upgraded to 500,000 and 5,000,000 respectively.

Visitor threshold is how mCaptcha determines which difficulty factor level to deploy. mCaptcha uses leaky bucket algorithm to keep the visitor threshold constantly updated within the configured cool down period. So, at any given moment the, the current visitor level will be the amount of traffic that was served in the cool down period specified.

`},{id:12,href:"/docs/webmasters/faq/",title:"Webmasters FAQ",description:"Frequently asked questions related to using mCaptcha as a webmaster",content:`

Easy Mode: Default cooldown period

When configuring mCaptcha in easy mode, the default cooldown period is set to 30 seconds.

How to get site key from dashboard?

  1. Go to “Site keys” on the side panel in the dashboard
Site key menu option on the dashboard, encircled in red.
  1. click on the clipboard button to copy the site key to your clipboard.
Copy site key to clipboard. Clipboard button is highlighted in the photo
`},{id:13,href:"/docs/help/",title:"Help",description:"Help mCaptcha.",content:""},{id:14,href:"/docs/webmasters/",title:"Webmasters",description:"Introduction to mCaptcha for webmasters",content:""},{id:15,href:"/docs/api/",title:"API",description:"Documentation for libraries used in mCaptcha",content:""},{id:16,href:"/docs/",title:"mCaptcha",description:"Docs mCaptcha",content:""},{id:17,href:"/docs/self-hosting/",title:"Self-Hosting",description:"Instructions to self-host mCaptcha",content:""}];e.add(n),userinput.addEventListener("input",s,!0),suggestions.addEventListener("click",o,!0);function s(){var n,i=this.value,s=e.search(i,5),o=suggestions.childNodes,r=0,c=s.length;for(suggestions.classList.remove("d-none"),s.forEach(function(e){n=document.createElement("div"),n.innerHTML="",a=n.querySelector("a"),t=n.querySelector("span:first-child"),d=n.querySelector("span:nth-child(2)"),a.href=e.href,t.textContent=e.title,d.textContent=e.description,suggestions.appendChild(n)});o.length>c;)suggestions.removeChild(o[r])}function o(){for(;suggestions.lastChild;)suggestions.removeChild(suggestions.lastChild);return!1}})()