Protect a route with an ALTCHA challenge
Run the ALTCHA challenge on a firewall, then add the application rule that sends unverified requests to it.
ALTCHA is an open-source CAPTCHA alternative that keeps bots and spam off a protected route. It answers a request with a challenge, and it runs as a function on a firewall. A rule on the application sends unverified requests to the challenge. Every step runs in Azion Console.
The function adds two endpoints to the application. /az-request-verify returns the challenge page, and /az-request-captcha validates the solution. A browser that solves the challenge receives a session cookie, so later requests pass without a new challenge.
ALTCHA runs inside Azion infrastructure and calls no third-party service. It collects no personal data, and the widget works with screen readers and other assistive technologies.
To run ALTCHA as the redirect target of Bot Manager, refer to Firewall best practices.
Prerequisites
- An Azion account. To create one, refer to How to create an account on Azion.
- The ALTCHA function on your account. ALTCHA is an integration from Azion Marketplace. To install it, refer to How to install an integration.
- The Edit Firewall permission on the account. It grants permission to view, create, edit, and remove a firewall, and it also requires the permission View Firewall.
- The Edit Applications permission on the account. The redirect rule changes an application, and this permission also requires the permission View Applications. Refer to Teams Permissions.
- An application, and the route the challenge protects. The examples use
/formas that route.
Create the firewall
ALTCHA runs on a firewall with the Functions module turned on. To create the firewall:
Access Azion Console > Firewall.
Enter a name for the firewall. For example: altcha firewall.
The firewall is saved, and the Functions Instances and Rules Engine tabs become available on the same page.
Instantiate the ALTCHA function
A function instance binds ALTCHA to one firewall and carries its configuration. To create the instance:
In the firewall you created, go to the Functions Instances tab.
Enter a name for the instance. For example: altcha instance.
In the function list, select ALTCHA. The Arguments tab loads.
(Optional) In the Arguments tab, enter the configuration in JSON. Every parameter is optional, and the function uses its default for each parameter you omit. For example:
For each parameter the function accepts, refer to Configuration parameters.
The instance appears in the Functions Instances tab. It does not run until a Rules Engine rule selects it.
Add the firewall rule that runs ALTCHA
A Rules Engine rule sets when the firewall runs ALTCHA. The criteria cover the protected route and both ALTCHA endpoints. To add the rule:
In the same firewall, go to the Rules Engine tab.
Enter a unique, descriptive name. For example: Run ALTCHA.
In the Criteria section, match the Request URI against /form, /az-request-verify, and /az-request-captcha. Replace /form with the route the challenge protects, such as /api/submit.
In the Behavior section, select Run Function and then the ALTCHA instance.
The firewall runs ALTCHA on every request whose URI matches the criteria. Changes can take a few minutes to propagate.
Add the application rule that starts the challenge
The application starts the flow. A request to the protected route without the X-Azcaptcha-Success header goes to /az-request-verify. To add the rule in the Rules Engine of the application:
In Azion Console, go to Applications and select the application the challenge protects.
Enter a unique, descriptive name. For example: Start ALTCHA challenge.
Set Phase to Request.
In the Criteria section, select the ${http_X_Azcaptcha_Success} variable and the does not exist operator.
Select the ${uri} variable, the is equal operator, and /form as the value.
In the Behavior section, select Redirect To (302 Found) and enter /az-request-verify as the destination.
A request to /form without a valid session cookie now goes to the ALTCHA challenge page. The verification flow starts there.
Customize the challenge page
By default, ALTCHA serves a white page that holds the widget. Three parameters change it: custom_html replaces the page, captcha_colors sets the colors of the widget, and captcha_localization sets its text.
To replace the page, set custom_html in the Arguments tab of the instance:
To show the widget messages in the language of your users, set captcha_localization:
Configuration parameters
The Arguments tab of the instance takes a JSON object. Every parameter is optional:
Each parameter, its type, and its default:
| Parameter | Type | Default | Description |
|---|---|---|---|
allowed_domains | Array of strings | ${host} | Sets the domains the function allows redirects to. The host of the application and relative redirects are always allowed. On an invalid value, the function ignores the parameter and logs a warning in Real-Time Events |
captcha_colors | Object | None | Sets the colors of the ALTCHA widget |
captcha_colors.base | String | Defined by ALTCHA | Base color of the ALTCHA widget, as a hex triplet |
captcha_colors.border | String | Defined by ALTCHA | Border color of the ALTCHA widget, as a hex triplet |
captcha_colors.border_focus | String | Defined by ALTCHA | Border color of the ALTCHA widget while it holds focus, as a hex triplet |
captcha_colors.error_text | String | Defined by ALTCHA | Color of the error messages in the ALTCHA widget, as a hex triplet |
captcha_colors.text | String | Defined by ALTCHA | Text color of the ALTCHA widget, as a hex triplet |
captcha_localization | Object | None | Sets the strings the ALTCHA widget shows |
captcha_localization.error | String | Defined by ALTCHA | Message shown when an error occurs while the user solves the challenge |
captcha_localization.label | String | Defined by ALTCHA | Message shown beside the checkbox the user selects |
captcha_localization.verified | String | Defined by ALTCHA | Message shown after the widget detects a correct solution. The script redirects the user on a correct solution, so most users never see it |
captcha_localization.verifying | String | Defined by ALTCHA | Message shown while the script verifies the solution |
cookie_max_age | Integer | 86400 | Sets the maximum age for the session cookie. A short value causes frequent challenges, and a long value reduces security |
cookie_secret | String | @z10N!${FUNCTION_VERSION} | Secret key that signs the session cookie |
custom_html | String | A white page that holds the ALTCHA widget | Replaces the layout of the challenge page. The function inserts the widget at the {/* azion_captcha */} tag, or at the end of the HTML body when the tag is absent |
status_code | Integer | 200 | Sets the status code of the challenge page response. On an invalid value, or on a status code that allows no response body such as 101, 204, 205, or 304, the function uses 200 |
Control headers and session cookies
ALTCHA sets HTTP headers that carry the state of the verification. Use them to debug the flow and to drive the logic of your application.
| Header | Description |
|---|---|
X-Azcaptcha-Success: true | The user solved the challenge |
X-Azcaptcha-Violation: true | The function detected an attempt to bypass the challenge |
ALTCHA also sets two cookies that hold the state of the verification session.
| Cookie | Description |
|---|---|
az_${FUNCTION_VERSION}_verify_payload | The raw data of the challenge solution |
az_${FUNCTION_VERSION}_verify_session | The signed session cookie that validates later requests without a new challenge |
Monitor the function logs in Real-Time Events for bypass attempts, and adjust the configuration on what the logs show.
Limitations
- HTTPS: ALTCHA uses the Web Crypto API, and that API runs only over HTTPS.
- Full URLs: a redirect parameter carries the scheme and the hostname.
- Reserved endpoints:
/az-request-verifyand/az-request-captchaserve ALTCHA only. The application must not use a URL that carries either term.