mirror of
https://github.com/germondai/trawl.git
synced 2026-08-17 12:11:23 +02:00
73 lines
2.2 KiB
Markdown
73 lines
2.2 KiB
Markdown
---
|
|
title: Session Cache
|
|
description: How TRAWL caches solved browser sessions in Redis to avoid unnecessary challenge work.
|
|
---
|
|
|
|
# Session Cache
|
|
|
|
The session cache is what makes Tier 2 possible. After a successful Tier 3 or Tier 4 solve, TRAWL
|
|
saves the extracted cookies and browser user agent in Redis. The next request to the same hostname
|
|
injects that state into a browser context and attempts to reuse the solved session.
|
|
|
|
## Storage format
|
|
|
|
Key: `session:{hostname}` (e.g. `session:nowsecure.nl`)
|
|
|
|
Value (JSON):
|
|
```typescript
|
|
interface SessionData {
|
|
cookies: Cookie[]
|
|
userAgent: string
|
|
savedAt: number // unix timestamp ms
|
|
}
|
|
```
|
|
|
|
TTL: `SESSION_TTL_SECONDS` (default 3600 seconds / 1 hour).
|
|
|
|
## Session key
|
|
|
|
The key is the **hostname only** — no path, no port, no protocol. This means all pages on a domain share one session:
|
|
|
|
```
|
|
https://example.com/ → session:example.com
|
|
https://example.com/page → session:example.com (same key)
|
|
https://sub.example.com/ → session:sub.example.com (different key)
|
|
```
|
|
|
|
Subdomains have separate sessions because WAF and application cookies can differ per subdomain.
|
|
|
|
## Lifecycle
|
|
|
|
```
|
|
Tier 3 succeeds
|
|
│
|
|
├── extract cookies from browser context
|
|
├── REDIS SET session:hostname → JSON EX SESSION_TTL_SECONDS
|
|
│
|
|
└── next request to same domain:
|
|
REDIS GET session:hostname
|
|
├── hit → Tier 2: inject cookies and navigate
|
|
└── miss → Tier 3: fresh solve, save to cache
|
|
```
|
|
|
|
## Invalidation
|
|
|
|
If Tier 2 navigates with cached state and still receives a recognized challenge wall, the orchestrator:
|
|
|
|
1. Calls `sessionCache.invalidate(domain)` — deletes the Redis key
|
|
2. Escalates to Tier 3 to get a fresh session
|
|
|
|
This handles provider cookies expiring or being rejected before the Redis TTL ends.
|
|
|
|
## Redis
|
|
|
|
TRAWL's cache backend is Redis 8.8. TRAWL talks to it with `new RedisClient(REDIS_URL)` from Bun's native Redis client (not ioredis).
|
|
|
|
```typescript
|
|
import { RedisClient } from 'bun'
|
|
|
|
const redis = new RedisClient('redis://localhost:6379')
|
|
await redis.set('session:example.com', JSON.stringify(data), 'EX', 3600)
|
|
const raw = await redis.get('session:example.com')
|
|
```
|