Repository navigation
Bypass Cloudflare 403 by sending browser-like request headers - #110
Conversation
emreertunc
left a comment
There was a problem hiding this comment.
Thanks for the fix. I found two issues that need to be addressed before approval.
-
cargo fmt --manifest-path src-tauri/Cargo.toml -- --checkcurrently fails. Please runcargo fmt --manifest-path src-tauri/Cargo.tomland commit the formatting changes. -
The new 403 error message says the session tokens are stale and tells users to remove and re-add the account. This contradicts the PR’s own explanation that a 403 is a Cloudflare challenge or permissions error, not an expired-token signal. The metadata flow also refreshes the token immediately before this request, so the guidance is misleading and may cause users to remove accounts unnecessarily.
Please change the message so it accurately describes the Cloudflare request failure without blaming stale tokens or recommending account removal.
a8299fe to
a8bee46
Compare
Prior to this change every request to chatgpt.com/backend-api was sent
with User-Agent: codex-cli/1.0.0 and no other browser signals, which
reliably triggered Cloudflare's bot-detection challenge and returned a
403 Forbidden response with 'Enable JavaScript and cookies to continue'.
Changes in src-tauri/src/api/usage.rs:
- Replace CODEX_USER_AGENT ('codex-cli/1.0.0') with BROWSER_USER_AGENT,
a current Chrome 136 / Windows 10 UA string that Cloudflare accepts.
- Add browser-like headers to build_chatgpt_headers():
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.9
Origin: https://chatgpt.com
Referer: https://chatgpt.com
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: same-origin
- Apply the same browser UA to the API-key warmup path in
warmup_with_api_key() for consistency.
- Add an explicit 403 guard in fetch_chatgpt_account_metadata() that
surfaces a human-readable error instead of a raw HTML blob, so users
understand what happened if a 403 still occurs after retry.
- Keep the 401-only token-refresh retry logic unchanged. A 403 is a
Cloudflare/permissions signal and must NOT trigger a token refresh;
doing so burns the refresh token and causes a refresh_token_reused
error on the next legitimate refresh call.
Tested: all accounts return 200 OK after this change with zero 403s
observed across multiple refresh cycles (confirmed via stdout log).
Fixes: Lampese#108
cargo fmt: - Collapsed multi-line use imports and headers.insert calls in usage.rs to satisfy cargo fmt --check (was failing CI) Error message: - Old: 'session tokens are stale, try removing and re-adding the account' - New: 'request likely blocked by Cloudflare bot detection, transient network issue, try again in a moment' The 403 is a Cloudflare bot-detection challenge, not an expired-token signal. The metadata flow already refreshes tokens before this request via ensure_chatgpt_tokens_fresh(), so blaming stale tokens was inaccurate and could cause users to unnecessarily remove accounts.
a8bee46 to
e78ada8
Compare
Thanks for the detailed review! Both issues are now addressed: Formatting — ran cargo fmt and committed the result. cargo fmt --check now passes. Error message — you're right, the old message was contradictory. A 403 from chatgpt.com is a Cloudflare bot-detection challenge, not a token expiry signal — especially since the code already calls ensure_chatgpt_tokens_fresh() before this request. Changed to: "Accounts check API returned 403 Forbidden. The request was likely blocked by Cloudflare bot detection. This is a transient network issue please try again in a moment." |
|
thanks for the contribution! |
- pin Tauri CLI to ~2.10.1 to match the 2.10 runtime; 2.9 built Linux bundles the updater could not identify (from upstream Lampese#190) - updater shows 'installing' after the download instead of offering a restart while the installer is still running - chatgpt.com requests send browser-like headers so Cloudflare stops answering with a 403 challenge (upstream Lampese#110); a challenge page that still slips through is treated as transient instead of greying the account out - drop appmenu-gtk-module before GTK starts, which crashed on launch on Linux desktops with a global menu (upstream Lampese#191) - unit tests for keeping MCP logins when switching Claude accounts
Problem
When refreshing account usage or metadata, requests to
chatgpt.com/backend-apiwere being blocked by Cloudflare with a
403 Forbiddenresponse:This happened because the requests used
User-Agent: codex-cli/1.0.0with noother browser signals, which Cloudflare's bot detection immediately flags.
Fixes #108
Solution
Replace the bot-like UA and add the standard headers a real browser sends:
codex-cli/1.0.0)application/json, text/plain, */*en-US,en;q=0.9https://chatgpt.comempty / cors / same-originAlso adds a clear human-readable error message on the
accounts/checkendpointif a 403 still occurs, instead of surfacing a raw HTML blob to the user.
What was intentionally NOT changed
Token refresh is still triggered on 401 only. A 403 from Cloudflare does
not mean the token is expired — refreshing on 403 burns the refresh token and
causes a
refresh_token_reusederror on the next legitimate refresh.Testing
Ran the production build locally and monitored stdout logs across multiple
refresh cycles. All accounts return
200 OKwith zero 403s observed.