Skip to content

Bot detection for FortiWeb is usually about one thing: deciding whether a visitor is a legitimate human, an automated script, or something in between, and then applying the right response without blocking real users. FortiWeb can handle a lot of application-layer security, but it is not a complete answer to modern bot traffic on its own; you still need a challenge/validation layer, clean server-side verification, and policies that separate abusive automation from normal traffic.

That matters because “bot detection” is not just rate limiting with a different label. A workable setup needs signals from the browser or app, a server decision point, and a way to validate that the token you received was actually issued for the current session or request. If you are protecting login, account creation, checkout, or password reset, the goal is less “spot every bot perfectly” and more “make automated abuse expensive while keeping friction low for humans.”

abstract flow showing browser signals, validation server, and decision branches

Where FortiWeb fits in a bot-defense stack

FortiWeb is commonly used as the perimeter policy layer: it can inspect requests, enforce application rules, and help reduce obvious abuse before traffic reaches your app. That is useful, but bot defense usually needs a second layer that is purpose-built for interactive challenge and token validation.

A practical architecture looks like this:

  1. FortiWeb filters obvious noise, malformed requests, and simple abuse patterns.
  2. The application serves a challenge or risk check only when needed.
  3. The client receives a pass token.
  4. Your backend validates the token server-to-server.
  5. You decide whether to allow, rate-limit, step-up, or block.

That “step 3 to step 4” part is where many deployments get weak. If the validation happens only in the browser, it is easier to replay or tamper with. If you validate on the server with request-specific context, the attacker has a much harder time turning a captured token into reusable access.

FortiWeb versus CAPTCHA-only thinking

FortiWeb can help you detect abusive patterns, but CAPTCHA is still useful when you need an explicit human verification step. The two are complementary, not interchangeable.

CapabilityFortiWebCAPTCHA / token validation layer
L7 request filteringYesLimited
Human verification challengeNot the main jobYes
Server-side token validationNot the main jobYes
Works well on login / signup / resetYes, as part of policyYes, especially when targeted
Reduces friction for trusted usersYesYes, if risk-based

The most reliable pattern is to use FortiWeb for traffic governance and a dedicated challenge system for proof-of-human checks on high-value workflows.

A simple integration pattern that holds up

If your application already sits behind FortiWeb, the challenge flow should remain straightforward. The browser or mobile app loads a lightweight challenge script, the user completes it if needed, and your server validates the resulting pass token before allowing the sensitive action.

A minimal server-side validation flow looks like this:

python
# English comments only
# Example: validate a pass token on your backend

import requests

url = "https://apiv1.captcha.la/v1/validate"
headers = {
    "X-App-Key": "your_app_key",
    "X-App-Secret": "your_app_secret",
    "Content-Type": "application/json",
}
payload = {
    "pass_token": "token_from_client",
    "client_ip": "203.0.113.10",
}

response = requests.post(url, json=payload, headers=headers, timeout=5)
result = response.json()

if result.get("success"):
    # Allow the action
    pass
else:
    # Deny or step up
    pass

The important part is the server boundary. The client should obtain the token, but your backend should be the one to trust or reject it. CaptchaLa’s validation endpoint is designed for that server-side decision point, and it supports a straightforward POST flow to https://apiv1.captcha.la/v1/validate with pass_token, client_ip, and your app credentials in headers.

If you need to issue a challenge from the server side, there is also a server-token endpoint at https://apiv1.captcha.la/v1/server/challenge/issue. That can be useful when you want the backend to decide when a challenge should exist in the first place, rather than always rendering one up front.

layered security diagram with WAF, challenge, validation, and app decision

Choosing the right friction level

Not every endpoint needs the same protection. The mistake I see most often is treating all traffic the same, which either creates too much friction or leaves high-value flows exposed.

A better approach is to classify endpoints by risk:

  1. Low risk: public pages, static content, most read-only endpoints
    Usually no challenge needed unless behavior changes.

  2. Medium risk: search, comments, contact forms, newsletter signup
    Consider lightweight challenge or risk-based triggering.

  3. High risk: login, password reset, account creation, checkout, gift-card redemption
    Require stronger proof of human interaction and server validation.

  4. Abuse-sensitive admin actions: invite generation, API key creation, payout changes
    Combine FortiWeb policies with strict server checks and audit logging.

This is also where first-party data matters. If your bot decision depends on the signals you collect directly from your own site or app, your logic is easier to reason about and less dependent on third-party assumptions. CaptchaLa is built around first-party data only, which makes it easier to keep the trust boundary inside your own application.

SDKs, languages, and deployment details that matter

If you are implementing bot detection across web and mobile clients, support breadth matters less than consistency. You want the same trust model whether the user is on a browser, iOS, Android, Flutter app, or Electron app.

Current integration options include:

  • Web SDKs for JavaScript, Vue, and React
  • Native SDKs for iOS, Android, Flutter, and Electron
  • Server SDKs for PHP and Go
  • UI available in 8 languages

Package references are also straightforward:

  • Maven: la.captcha:captchala:1.0.2
  • CocoaPods: Captchala 1.0.2
  • pub.dev: captchala 1.3.2
  • Server SDKs: captchala-php, captchala-go

That breadth helps when FortiWeb protects a mixed environment. For example, a browser flow can use the JS SDK, while a mobile flow can use the native SDK, and both can validate against the same backend endpoint. The user experience stays consistent, and your operations team only has one policy model to maintain.

A few implementation details are worth being strict about:

  • Always validate on the server.
  • Pass the client IP if your policy uses it.
  • Keep tokens short-lived.
  • Tie challenge decisions to the endpoint and session context.
  • Log challenge outcomes so you can tune policies later.

How this compares to common alternatives

Teams often ask how this differs from reCAPTCHA, hCaptcha, or Cloudflare Turnstile. The honest answer is that the right choice depends on your operating constraints.

  • reCAPTCHA is widely recognized and easy to find documentation for, but some teams prefer more control over data handling and UX.
  • hCaptcha is often chosen for privacy or control reasons, and it supports challenge flows that work well in many applications.
  • Cloudflare Turnstile is attractive when you are already using Cloudflare’s edge stack and want a lower-friction approach.

Those tools can all be useful. The real question is whether the validation and policy logic fit your architecture, especially when FortiWeb is already in the path. If your stack already includes a WAF, you may want a challenge system that is easy to place behind it, easy to verify on your own backend, and easy to apply selectively instead of globally.

CaptchaLa can fit that role without forcing you into a full-stack redesign. You can start with a small number of sensitive endpoints, validate through the documented server API, and expand only when you see the need. The free tier covers 1,000 validations per month, Pro is sized for roughly 50K-200K, and Business goes up to 1M, which makes it practical to test in a controlled way before rolling out more broadly.

A deployment checklist for FortiWeb + bot validation

Before you ship, make sure these are in place:

  1. FortiWeb rules for malformed traffic, rate spikes, and obvious abuse.
  2. A challenge trigger for high-risk endpoints, not every request.
  3. Backend validation of pass tokens using your app key and secret.
  4. Logging for challenge issued, validation passed, validation failed, and timeout.
  5. A rollback path if a new policy causes user friction.
  6. Separate handling for web, iOS, Android, Flutter, and Electron where relevant.
  7. Periodic review of false positives and unusual traffic patterns.

If you do only one thing, make it this: keep the trust decision on the server, not in the client. That is the line between “a security widget” and an actual control.

Where to go next: review the integration details in the docs or check pricing if you want to test a small FortiWeb-protected rollout first.

Articles are CC BY 4.0 — feel free to quote with attribution