# Vulnerability Summary ## Vulnerability Overview OpenClaw has a sensitive information leakage vulnerability during Cross-Origin Redirects. When the application performs a cross-origin redirect, it incorrectly passes HTTP request headers containing authentication credentials (such as the `Authorization` header and `Cookie` header) to the target server. This may lead to users' sensitive authentication information being leaked to untrusted third-party domains. ## Impact Scope - **Affected Components**: `src/infra/net/fetch-guard.ts` and `src/infra/net/redirect-headers.ts` - **Trigger Scenario**: When a `fetch` request undergoes a cross-origin redirect. - **Leaked Data**: Sensitive headers such as `Authorization` (authentication token), `Cookie` (session information), etc. ## Remediation Plan 1. **Add Safe Header Whitelist**: In `src/infra/net/redirect-headers.ts`, define the `CROSS_ORIGIN_REDIRECT_SAFE_HEADERS` set, allowing only non-sensitive headers such as `Accept`, `User-Agent` to be retained during redirects. 2. **Filter Sensitive Headers**: Introduce the `retainSafeHeadersForCrossOriginRedirect` function in `src/infra/net/fetch-guard.ts`. 3. **Intercept Redirect Requests**: In the `fetchWithGuard` function, when a redirect is detected, call the filtering function above to remove headers containing sensitive information, ensuring that cross-origin requests do not include authentication credentials. ## Key Code Extract **src/infra/net/redirect-headers.ts (New safe header definition)** ```typescript const CROSS_ORIGIN_REDIRECT_SAFE_HEADERS = new Set([ "accept", "accept-encoding", "accept-language", "cache-control", "content-language", "content-type", "if-match", "if-modified-since", "if-none-match", "if-unmodified-since", "pragma", "range", "user-agent", ]); export function retainSafeHeadersForCrossOriginRedirect( headers?: HeadersInit | Record | undefined, ): Record | undefined { if (!headers) { return headers; } const incoming = new Headers(headers); const safeHeaders: Record = {}; for (const [key, value] of incoming.entries()) { if (CROSS_ORIGIN_REDIRECT_SAFE_HEADERS.has(key.toLowerCase())) { safeHeaders[key] = value; } } return safeHeaders; } ``` **src/infra/net/fetch-guard.ts (Apply filtering logic)** ```typescript import { retainSafeHeadersForCrossOriginRedirect } from "../redirect-headers.js"; // ... function retainSafeHeadersForCrossOriginRedirect(init?: RequestInit): RequestInit | undefined { if (!init?.headers) { return init; } return { ...init, headers: retainSafeHeadersForCrossOriginRedirectHeaders(init.headers), }; } export async function fetchWithGuard(params: GuardedFetchOptions): Promise { // ... // Apply filtering in redirect handling logic // ... } ```