T09 · Insecure Skill Coding Practices
Error
- Location
- src/lib/platform.ts:60
- Finding
- Session Cookie Exfiltration Through Unrestricted API Host Overrides<![CDATA[ ## Vulnerability Details **File Location**: `src/lib/platform.ts:60-68`; sensitive headers are constructed and transmitted in `src/lib/client.ts:56-105` **Vulnerability Type**: Arbitrary destination for authenticated requests **Risk Level**: Critical ### Vulnerable Code ```ts // src/lib/platform.ts:60-68 export function resolvePlatform(explicit?: string): PlatformConfig { const raw = (explicit || process.env.REDBOOK_PLATFORM || "xhs").toLowerCase(); const base = raw === "rednote" || raw === "global" ? PLATFORMS.rednote : PLATFORMS.xhs; return { ...base, edithHost: process.env.REDBOOK_EDITH_HOST || base.edithHost, creatorHost: process.env.REDBOOK_CREATOR_HOST || base.creatorHost, }; } ``` ```ts // src/lib/client.ts:56-81 private baseHeaders(): Record<string, string> { return { "user-agent": USER_AGENT, "content-type": "application/json", cookie: cookiesToString(this.cookies), origin: this.platform.homeUrl, referer: `${this.platform.homeUrl}/`, }; } private async mainApiGet( uri: string, params?: Record<string, string | number | string[]> ): Promise<unknown> { const fullUri = buildGetUri(uri, params); const url = `${this.platform.edithHost}${fullUri}`; const send = (signFormat: SignFormat) => fetch(url, { method: "GET", headers: { ...this.baseHeaders(), ...signMainApi("GET", uri, this.cookies, params, undefined, undefined, this.platform.signLocation, signFormat), }, }); ``` ```ts // src/lib/client.ts:95-105 private async mainApiPost( uri: string, data: Record<string, unknown> ): Promise<unknown> { const signHeaders = signMainApi("POST", uri, this.cookies, undefined, data, undefined, this.platform.signLocation); const url = `${this.platform.edithHost}${uri}`; const res = await fetch(url, { method: "POST", headers: { ...this.baseHeaders(), ...signHeaders }, body: JSON.stringify(data), }); ``` ### Technical Analysis The client legitimately nee ...[truncated 2380 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove `REDBOOK_EDITH_HOST` and `REDBOOK_CREATOR_HOST` overrides from production builds. 2. Allowlist exact authenticated request origins: - `https://edith.xiaohongshu.com` - `https://creator.xiaohongshu.com` - `https://webapi.rednote.com` - `https://creator.rednote.com` 3. Parse destinations with `new URL()` and compare `url.origin` against the allowlist before constructing any request. 4. Refuse credentials on non-HTTPS destinations and reject URLs containing usernames, alternate ports, deceptive suffixes, or subdomains not explicitly approved. 5. Add a second destination check immediately before attaching the `Cookie` header, so future configuration changes cannot bypass the policy. 6. If alternate hosts are required for development, place the feature behind an explicit unsafe-development option that is unavailable in the published CLI. Development requests should use test credentials rather than browser sessions. 7. Add tests confirming that values such as `https://attacker.example`, `http://localhost`, and `https://edith.xiaohongshu.com.attacker.example` cannot receive cookies. 8. Advise users who may have run the CLI with untrusted host overrides to log out and back in to rotate their sessions. ]]>
