Skip to content

Cloudflare WAF and 5-second challenge solver

Solve Cloudflare WAF and 5-second challenge pages to a cf_clearance cookie.

Solve Cloudflare WAF and 5-second challenge pages too: a task returns the cf_clearance cookie with the user agent it was issued for.

Cloudflare WAF, "Just a moment..." and the 5-second challenge

Three names people search for, and one page to solve: the interstitial challenge Cloudflare shows in front of a site. A CloudflareChallengeTask passes it, whatever it is called.

Cloudflare WAF challenge
A site's Cloudflare WAF rules (custom rules, rate limiting rules and IP Access rules) can answer a request with a challenge instead of the page, when the rule's action is Managed Challenge, Non-Interactive Challenge or Interactive Challenge. Bot Fight Mode and Under Attack mode show the same page.
"Just a moment..." and "Checking your browser"
The interstitial challenge page itself: a full-page screen, sent with HTTP 403 and the header cf-mitigated: challenge, that runs Cloudflare's checks before the visitor reaches the page. "Checking your browser before accessing..." is its older wording, which Cloudflare's reference still uses for Under Attack mode.
The 5-second challenge
The old name for Cloudflare's JavaScript challenge, after the few seconds its page took. Today it is a Managed Challenge or a Non-Interactive Challenge (API value js_challenge), which Cloudflare says typically takes less than five seconds.
cf_clearance
The cookie a browser earns by passing any of them. It lets that visitor through until the site's Challenge Passage time runs out, and it is what a challenge task returns.

What a challenge task returns

You send the page's URL and your proxy. The result is what your own client needs to be let through: use all three together, or the site challenges you again.

  • The cf_clearance cookie

    The cookie Cloudflare sets once its challenge is passed, which lets later requests to the site through.

  • The user agent it was issued for

    Cloudflare ties the cookie to the browser that earned it, so your requests must send the same User-Agent header.

  • Your proxy, used for the solve

    Send the proxy your later requests will use: the cookie is meant to be replayed from the address that earned it.

One request, one clearance

Create a CloudflareChallengeTask with the page's URL and your proxy, read it until it ends, then send the cf_clearance cookie with its user agent through the same proxy. The sample points at our own test page behind a managed challenge, so it runs as copied.

Cloudflare WAF and 5-second challenge, your proxy$1.20per 1,000 solved tasks, nothing for a failed one
See every price
#!/usr/bin/env bash
# Pass this page's Cloudflare challenge through your proxy with createTask, then load the page
# with the clearance.
set -euo pipefail
API=${ZEROCAPTCHA_API:-https://api.zerocaptcha.io}
KEY=${ZEROCAPTCHA_KEY:?Set ZEROCAPTCHA_KEY to your API key, zc_live_..., from the dashboard.}
PROXY=${PROXY_URL:?Set PROXY_URL to your proxy, such as http://user:pass@proxy.example.net:8080}
PAGE=https://zerocaptcha.io/captcha-test/cloudflare-managed-challenge

# 1. createTask for this page, through the proxy you will browse with: the clearance only works
#    from its address. CALLBACK_URL, when set, is called with the result when the task ends.
BODY=$(jq -n --arg key "$KEY" --arg proxy "$PROXY" --arg callback "${CALLBACK_URL:-}" '{
  clientKey: $key,
  task: {
    type: "CloudflareChallengeTask",
    websiteURL: "https://zerocaptcha.io/captcha-test/cloudflare-managed-challenge",
    proxy: $proxy
  },
  callbackUrl: (if $callback == "" then null else $callback end)
}')
CREATED=$(curl -sS --fail-with-body "$API/createTask" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d "$BODY")
# errorId 1 is a refusal: errorCode and errorDescription say why.
if [ "$(jq -r .errorId <<<"$CREATED")" != 0 ]; then echo "$CREATED" >&2; exit 1; fi
TASK_ID=$(jq -r .taskId <<<"$CREATED")

# 2. getTaskResult every 2 seconds until the task is ready; errorId 1 means it failed, unpaid.
while :; do
  sleep 2
  RESULT=$(curl -sS --fail-with-body "$API/getTaskResult" \
    -H "Content-Type: application/json" \
    -d "$(jq -n --arg key "$KEY" --arg id "$TASK_ID" '{clientKey: $key, taskId: $id}')")
  if [ "$(jq -r .errorId <<<"$RESULT")" != 0 ]; then echo "$RESULT" >&2; exit 1; fi
  if [ "$(jq -r .status <<<"$RESULT")" = ready ]; then break; fi
done
CLEARANCE=$(jq -r .solution.cookies.cf_clearance <<<"$RESULT")
USER_AGENT=$(jq -r .solution.userAgent <<<"$RESULT")

# 3. Come back as the browser that passed: the same proxy, user agent and cookie. A client whose
#    TLS does not look like that browser may be challenged again (use curl-impersonate).
curl -sS -o /dev/null -w "page: HTTP %{http_code}\n" \
  -x "$PROXY" -A "$USER_AGENT" -b "cf_clearance=$CLEARANCE" "$PAGE"
curl -sS -x "$PROXY" -A "$USER_AGENT" -b "cf_clearance=$CLEARANCE" \
  "https://zerocaptcha.io/api/v1/demo/clearance"

Challenge page or Cloudflare Turnstile widget?

A challenge page, the "Just a moment…" screen a Cloudflare WAF rule shows, once called the 5-second challenge, stands in front of a whole site. Passing it sets the cf_clearance cookie, and your client then browses the site with that cookie, its user agent and its address.

A Turnstile widget sits inside a page, usually a form. It produces a single-use token that the form sends and the site verifies within 300 seconds. That is what the Cloudflare Turnstile solver returns today.

Both are tasks on the same API, with the same prepaid balance and the same rule: you pay only when a task succeeds.

Cloudflare WAF and 5-second challenge guides

Cloudflare challenges, errors and WAF rules

Every article on the ZeroCaptcha blog

Test it on a live Cloudflare WAF challenge page

A page behind each kind of Cloudflare challenge, and one with a pre-clearance widget, to point a challenge task at. Each shows whether your browser holds a cf_clearance cookie.

Cloudflare WAF and 5-second challenge questions

Are Cloudflare WAF and 5-second challenge pages supported today?

Yes. A challenge task passes the page a Cloudflare WAF rule shows through your proxy, and returns the cf_clearance cookie with the user agent it was issued for, charged only when it succeeds.

What is the Cloudflare 5-second challenge?

The old name for Cloudflare's JavaScript challenge page, after the few seconds it took. Today a WAF rule shows a Managed or Non-Interactive Challenge in its place, which Cloudflare says typically takes less than five seconds. A challenge task solves either, and returns the cf_clearance cookie.

Is "Just a moment..." a Cloudflare WAF challenge?

Usually. "Just a moment..." is the challenge page Cloudflare shows when a WAF rule, Bot Fight Mode or Under Attack mode challenges a request. It answers with HTTP 403 and the header cf-mitigated: challenge. A block, such as error 1020, is a refusal rather than a challenge, and no task can pass it.

How is a challenge page different from Cloudflare Turnstile?

A challenge page stands in front of a whole site and, once passed, sets the cf_clearance cookie. Turnstile is a widget inside a page that gives its form a single-use token. They need different tasks.

Why must I reuse the user agent and proxy?

Cloudflare ties cf_clearance to the visitor and device it was issued to: in practice, the browser's user agent and usually its address. Requests with another user agent or from another address are challenged again.

Will I pay for challenges that fail?

No. Every ZeroCaptcha task holds its price and charges it only when it succeeds; a failed or expired task costs nothing.