autoreg-skills-max: initial public release (restored, redacted, hardened)
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
# LobeHub Cloud (app.lobehub.com) Registration via FlareSolverr CDP
|
||||
|
||||
> **Date:** 2026-07-05
|
||||
> **Status:** Confirmed working — 2 accounts successfully registered
|
||||
> **Contrasts with:** `references/lobehub-selfhosted-autoreg.md` (self-hosted via Docker Compose + Better Auth)
|
||||
|
||||
## Problem
|
||||
|
||||
LobeHub Cloud (`app.lobehub.com`) uses **double Cloudflare protection**:
|
||||
1. **Cloudflare WAF** — blocks datacenter IPs entirely (DO, AWS, any VPS). Returns "Attention Required! | Cloudflare" for headless browsers and direct curl.
|
||||
2. **Cloudflare Turnstile** — on the signup form, requires a Turnstile token for API calls to `POST /api/auth/sign-up/email`.
|
||||
|
||||
## The FlareSolverr Trap
|
||||
|
||||
FlareSolverr (running on DO via Docker `ghcr.io/flaresolverr/flaresolverr:latest`) can bypass Cloudflare WAF layer #1, but **its `request.post` command strips ALL custom headers**, including `x-captcha-response`.
|
||||
|
||||
**Confirmed via httpbin.org test:**
|
||||
- FlareSolverr sends custom `postData` as `application/x-www-form-urlencoded`
|
||||
- Headers like `X-Test-Header`, `x-captcha-response` are completely absent from the received request
|
||||
- The browser navigates naturally but does not forward arbitrary headers
|
||||
|
||||
Result: LobeHub API receives the POST with form-encoded body and NO captcha token → `{"code":"CAPTCHA_REQUIRED"}`
|
||||
|
||||
## Solution: CDP (Chrome DevTools Protocol) Direct Connection
|
||||
|
||||
FlareSolverr runs Chromium with `--remote-debugging-port` inside the Docker container. Connect to it directly and execute JavaScript `fetch()` calls in the browser context.
|
||||
|
||||
### Finding the CDP Port
|
||||
|
||||
```bash
|
||||
# Inside the FlareSolverr container
|
||||
ps aux | grep 'remote-debugging-port' | grep -oP 'remote-debugging-port=\K\d+'
|
||||
# Returns: 39013 (or similar)
|
||||
```
|
||||
|
||||
The port is on `127.0.0.1` inside the container. Access via `docker exec`.
|
||||
|
||||
### Getting the WebSocket URL
|
||||
|
||||
```python
|
||||
import requests
|
||||
pages = requests.get("http://127.0.0.1:39013/json").json()
|
||||
ws_url = pages[0]["webSocketDebuggerUrl"]
|
||||
# e.g. ws://127.0.0.1:39013/devtools/page/FCBFE79E...
|
||||
```
|
||||
|
||||
### Executing JS fetch with captcha header
|
||||
|
||||
```python
|
||||
import asyncio, json, websockets, requests as rq
|
||||
|
||||
async def signup(email, password, token):
|
||||
pages = rq.get("http://127.0.0.1:39013/json").json()
|
||||
ws_url = pages[0]["webSocketDebuggerUrl"]
|
||||
|
||||
async with websockets.connect(ws_url, max_size=10**7) as ws:
|
||||
mid = 1
|
||||
async def cmd(method, params={}):
|
||||
nonlocal mid
|
||||
cm = {"id": mid, "method": method, "params": params}
|
||||
await ws.send(json.dumps(cm))
|
||||
mid += 1
|
||||
return json.loads(await ws.recv())
|
||||
|
||||
# Navigate to LobeHub (gets cf_clearance cookie)
|
||||
await cmd("Page.navigate", {"url": "https://app.lobehub.com/signup"})
|
||||
await asyncio.sleep(4)
|
||||
|
||||
# Execute fetch inside the browser context
|
||||
js = f"""
|
||||
(async () => {{
|
||||
const resp = await fetch('/api/auth/sign-up/email', {{
|
||||
method: 'POST',
|
||||
headers: {{'Content-Type': 'application/json', 'x-captcha-response': '{token}'}},
|
||||
body: JSON.stringify({{email: '{email}', password: '{password}', name: 'test'}})
|
||||
}});
|
||||
const text = await resp.text();
|
||||
return JSON.stringify({{status: resp.status, body: text.substring(0,500)}});
|
||||
}})()
|
||||
"""
|
||||
|
||||
r = await cmd("Runtime.evaluate", {"expression": js, "awaitPromise": True})
|
||||
val = r.get("result",{}).get("result",{}).get("value","")
|
||||
return json.loads(val)
|
||||
```
|
||||
|
||||
### Solving Turnstile via 2captcha
|
||||
|
||||
```
|
||||
Sitekey: 0x4AAAAAACxm5ZI_WCU13SgI
|
||||
Pageurl: https://app.lobehub.com/signup
|
||||
Method: turnstile
|
||||
```
|
||||
|
||||
Standard 2captcha flow (`in.php` → `res.php` polling). Token lifetime ~2min, solve time ~20-40s.
|
||||
|
||||
### Verifying Signup Success
|
||||
|
||||
Successful response (HTTP 200):
|
||||
```json
|
||||
{"token": null, "user": {"name": "test", "email": "user@outlook.com", "emailVerified": false, "id": "user_xxx..."}}
|
||||
```
|
||||
|
||||
`emailVerified: false` means verification email was sent. Login returns 404 until verified.
|
||||
|
||||
## Known Working Domains
|
||||
|
||||
| Domain | Status | Notes |
|
||||
|--------|--------|-------|
|
||||
| @outlook.com | ✅ Works | Verification email arrives |
|
||||
| @hotmail.com | ✅ Works | Same Microsoft infra |
|
||||
| @live.com | ✅ Works | Same Microsoft infra |
|
||||
| @reforrm.me | ❌ 404 | Domain likely blocked |
|
||||
| @t-online.de | ❌ No delivery | LobeHub emails don't arrive (earlier testing) |
|
||||
| @gmail.com | ⚠️ Untested | Need app password for IMAP |
|
||||
|
||||
## Pitfalls
|
||||
|
||||
1. **CDP port changes each time FlareSolverr Chrome restarts** — always discover it dynamically
|
||||
2. **Page navigation is required** — the Chrome browser needs to be ON app.lobehub.com first. Cookies/session from other pages don't carry over for `fetch()` calls. Always call `Page.navigate` before the fetch.
|
||||
3. **2captcha balance depletes fast** — ~$0.15 per solve. With ~$2.15 balance, only ~14 registrations possible. For 500 accounts need ~$75.
|
||||
4. **Single browser session limits throughput** — FlareSolverr runs one Chrome instance. All CDP calls go through the same browser context. Don't parallelize.
|
||||
5. **Verification email needed before login** — Signup creates the account but login returns 404 until email is verified (click verification link).
|
||||
Reference in New Issue
Block a user