From 0e213ca4ecf9e8a2ec214683c5d54cb20fa0d31d Mon Sep 17 00:00:00 2001 From: pucedoteth Date: Fri, 21 Aug 2026 16:00:02 +0200 Subject: [PATCH] orchestrate: redact the whole value in redactBody, not up to the first space The sensitive-assignment pattern matched `\S+` after the separator, so it consumed only the auth scheme in `Authorization: Bearer ` and only the first word of a quoted value. `redactBody` returned "Authorization=[redacted] " with reasons reporting a successful redaction. Match to end of line instead, and cover the branch with tests -- it had none. --- .../scripts/__tests__/redact-body.test.ts | 22 +++++++++++++++++++ .../orchestrate/scripts/core/redact-body.ts | 4 +++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/orchestrate/skills/orchestrate/scripts/__tests__/redact-body.test.ts b/orchestrate/skills/orchestrate/scripts/__tests__/redact-body.test.ts index a7fbbd4a..5500233b 100644 --- a/orchestrate/skills/orchestrate/scripts/__tests__/redact-body.test.ts +++ b/orchestrate/skills/orchestrate/scripts/__tests__/redact-body.test.ts @@ -41,6 +41,28 @@ describe("redactBody", () => { expect(redactBody(`\`${sha}\``).reasons).toEqual([]); }); + test("redacts the credential after an auth scheme, not just the scheme", () => { + const jwt = "eyJhbGciOiJIUzI1NiJ9.SECRETPAYLOAD.sig"; + const result = redactBody(`Authorization: Bearer ${jwt}`); + + expect(result.text).toBe("Authorization=[redacted]"); + expect(result.text).not.toContain(jwt); + expect(result.reasons).toContain("contains sensitive key"); + }); + + test("redacts a quoted value containing spaces", () => { + const result = redactBody('export TOKEN="my secret value"'); + + expect(result.text).toBe("export TOKEN=[redacted]"); + expect(result.text).not.toContain("secret value"); + }); + + test("redacts only the offending line", () => { + const result = redactBody("password: hunter2\nnext line stays"); + + expect(result.text).toBe("password=[redacted]\nnext line stays"); + }); + test("allows concise operational context", () => { const result = redactBody("blocked: docker rate-limit on redis:7"); diff --git a/orchestrate/skills/orchestrate/scripts/core/redact-body.ts b/orchestrate/skills/orchestrate/scripts/core/redact-body.ts index 4623f107..0f0b98fb 100644 --- a/orchestrate/skills/orchestrate/scripts/core/redact-body.ts +++ b/orchestrate/skills/orchestrate/scripts/core/redact-body.ts @@ -1,7 +1,9 @@ const MAX_BODY_CHARS = 2_048; const SENSITIVE_KEY_RE = /token|secret|password|api[_-]?key|authorization/i; +// Value runs to end of line: `\S+` stopped at the first space, which left the +// credential behind in `Authorization: Bearer ` and in quoted values. const SENSITIVE_ASSIGNMENT_RE = - /\b(token|secret|password|api[_-]?key|authorization)\b\s*[:=]\s*\S+/gi; + /\b(token|secret|password|api[_-]?key|authorization)\b\s*[:=]\s*\S.*/gi; const PATH_PATTERNS = [ { re: /^\/workspace\/\S*/gm, reason: "contains /workspace path" }, { re: /^\/Users\/\S*/gm, reason: "contains /Users path" },