fix: critical bugs, serverless stability, and security hardening
Bug Fixes: - Fix rate limiter API mismatch: check() -> checkAsync() in index.ts, worker.ts, api/relay.ts - Fix WebSocket SSRF silent drop: return error Response instead of undefined - Fix isDevMode() default: changed from true to false (production-safe) - Fix process.env -> env bindings in worker.ts requireAuth for Cloudflare Workers - Fix Bun.file() crash in Workers: add try/catch with fallback - Fix Bun.CryptoHasher -> Web Crypto API in mimo-auth.ts for Workers compat Architecture: - Add public methods to ProxyPool (getEntryAtIndex, getProxyUrlAtIndex, getCurrentIndex, setCurrentIndex) to remove all 'as any' casts in SessionProxyPool - Add addProxy() method for manual proxy management - Add loadAsync(), tryLoadAsync(), loadFromString() to ProxyPool Serverless Stability: - Add optional DNS rebinding protection via SSRF_DNS_CHECK env flag - CORS cache now auto-invalidates when CORS_ORIGIN env changes - Rate limiter max-size eviction (10k keys) prevents unbounded memory growth Tests: - Fix type assertions in test files (body as Record<string, unknown>) - All 153 tests pass, typecheck clean
This commit is contained in:
@@ -29,8 +29,10 @@ const EXPIRY_BUFFER_MS = 300_000; // 5 minutes
|
||||
*
|
||||
* Format: `sha256(hostname|platform|arch|cpu|username)`
|
||||
* This matches the 9Router reference implementation.
|
||||
*
|
||||
* Uses Web Crypto API (available in Bun, Workers, and Node.js 20+).
|
||||
*/
|
||||
function generateDeviceFingerprint(): string {
|
||||
async function generateDeviceFingerprint(): Promise<string> {
|
||||
const hostname = os.hostname();
|
||||
const platform = process.platform;
|
||||
const arch = process.arch;
|
||||
@@ -39,9 +41,11 @@ function generateDeviceFingerprint(): string {
|
||||
const username = process.env.USER ?? process.env.USERNAME ?? "unknown";
|
||||
|
||||
const raw = `${hostname}|${platform}|${arch}|${cpuModel}|${username}`;
|
||||
const hasher = new Bun.CryptoHasher("sha256");
|
||||
hasher.update(raw);
|
||||
return hasher.digest("hex") as string;
|
||||
const encoder = new TextEncoder();
|
||||
const data = encoder.encode(raw);
|
||||
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
|
||||
const hashArray = new Uint8Array(hashBuffer);
|
||||
return Array.from(hashArray).map((b) => b.toString(16).padStart(2, "0")).join("");
|
||||
}
|
||||
|
||||
// --- JWT bootstrap -----------------------------------------------------------
|
||||
@@ -55,7 +59,7 @@ function generateDeviceFingerprint(): string {
|
||||
* @throws If the bootstrap request fails or returns an unexpected response.
|
||||
*/
|
||||
async function bootstrapJwt(): Promise<string> {
|
||||
const fingerprint = generateDeviceFingerprint();
|
||||
const fingerprint = await generateDeviceFingerprint();
|
||||
|
||||
const resp = await fetch(MIMO_BOOTSTRAP_URL, {
|
||||
method: "POST",
|
||||
|
||||
Reference in New Issue
Block a user