fix: add redaction patterns for JWTs, Basic auth, and custom security headers in logs.tail#67041
fix: add redaction patterns for JWTs, Basic auth, and custom security headers in logs.tail#67041Magicray1217 wants to merge 1 commit into
Conversation
… headers The logs.tail redaction missed several credential formats that could leak secrets to operator.read clients: - Generic JWTs (eyJ... three-segment base64url tokens) - Basic auth headers (Authorization: Basic ...) - Custom security headers (X-OpenClaw-Token, x-pomerium-jwt-assertion, X-Api-Key, X-Auth-Token) Added patterns and tests for all four cases. Fixes openclaw#66832
Greptile SummaryAdds redaction patterns for generic JWTs, Basic auth headers, and custom security headers (
Confidence Score: 5/5Safe to merge; the new patterns work correctly in the common case and all remaining findings are P2. All findings are P2. The \b boundary quirk in the Basic auth pattern only affects trailing base64 padding (not the credential itself), and the test organisation issue doesn't affect runtime behaviour. No P0 or P1 defects were found. src/logging/redact.ts line 44 (Basic auth pattern \b); src/logging/redact.test.ts (test describe-block placement) Prompt To Fix All With AIThis is a comment left during a code review.
Path: src/logging/redact.ts
Line: 44
Comment:
**`\b` prevents redacting trailing base64 padding**
The `\b` word-boundary at the end of this pattern causes greedy backtracking to stop before any trailing `=` or `/` characters, since those are non-word chars. For example, `dXNlcm5hbWU6cGFzc3dvcmQ=` would be matched as `dXNlcm5hbWU6cGFzc3dvcmQ` (23 chars), leaving the trailing `=` unredacted in the log output. The test passes because it only checks that the full original string is absent, not that the padding is masked too.
Since the character class `[A-Za-z0-9+/=]{18,}` already stops greedily at a non-matching character, the `\b` is not needed for boundary detection here and actively hurts correctness.
```suggestion
String.raw`Authorization\s*[:=]\s*Basic\s+([A-Za-z0-9+/=]{18,})`,
```
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: src/logging/redact.test.ts
Line: 212-238
Comment:
**Tests placed in wrong describe block; JWT test doesn't isolate the new pattern**
All four new tests call `redactSensitiveText` but are nested inside `describe("redactSensitiveLines", ...)`. They should live in the `describe("redactSensitiveText", ...)` block above (or a new dedicated block).
Additionally, the `"masks generic JWT tokens"` test uses `Authorization: Bearer ${jwt}` as input. This string is already matched by the pre-existing Bearer pattern (`Authorization\s*[:=]\s*Bearer\s+...`), so the test never actually exercises the new `eyJ…` JWT pattern. A standalone JWT (e.g. in a log line without a `Bearer` prefix) would better isolate the new pattern:
```ts
// tests the new eyJ JWT pattern directly
const input = `x-pomerium-jwt-assertion: ${jwt}`;
// or simply
const input = `some log line: jwt=${jwt}`;
```
How can I resolve this? If you propose a fix, please make it concise.Reviews (1): Last reviewed commit: "fix: add redaction patterns for JWTs, Ba..." | Re-trigger Greptile |
| // Generic JWTs (three base64url segments separated by dots). | ||
| String.raw`\b(eyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,})\b`, | ||
| // Basic auth headers. | ||
| String.raw`Authorization\s*[:=]\s*Basic\s+([A-Za-z0-9+/=]{18,})\b`, |
There was a problem hiding this comment.
\b prevents redacting trailing base64 padding
The \b word-boundary at the end of this pattern causes greedy backtracking to stop before any trailing = or / characters, since those are non-word chars. For example, dXNlcm5hbWU6cGFzc3dvcmQ= would be matched as dXNlcm5hbWU6cGFzc3dvcmQ (23 chars), leaving the trailing = unredacted in the log output. The test passes because it only checks that the full original string is absent, not that the padding is masked too.
Since the character class [A-Za-z0-9+/=]{18,} already stops greedily at a non-matching character, the \b is not needed for boundary detection here and actively hurts correctness.
| String.raw`Authorization\s*[:=]\s*Basic\s+([A-Za-z0-9+/=]{18,})\b`, | |
| String.raw`Authorization\s*[:=]\s*Basic\s+([A-Za-z0-9+/=]{18,})`, |
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/logging/redact.ts
Line: 44
Comment:
**`\b` prevents redacting trailing base64 padding**
The `\b` word-boundary at the end of this pattern causes greedy backtracking to stop before any trailing `=` or `/` characters, since those are non-word chars. For example, `dXNlcm5hbWU6cGFzc3dvcmQ=` would be matched as `dXNlcm5hbWU6cGFzc3dvcmQ` (23 chars), leaving the trailing `=` unredacted in the log output. The test passes because it only checks that the full original string is absent, not that the padding is masked too.
Since the character class `[A-Za-z0-9+/=]{18,}` already stops greedily at a non-matching character, the `\b` is not needed for boundary detection here and actively hurts correctness.
```suggestion
String.raw`Authorization\s*[:=]\s*Basic\s+([A-Za-z0-9+/=]{18,})`,
```
How can I resolve this? If you propose a fix, please make it concise.| it("masks generic JWT tokens", () => { | ||
| const jwt = | ||
| "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"; | ||
| const input = `Authorization: Bearer ${jwt}`; | ||
| const output = redactSensitiveText(input, { mode: "tools", patterns: defaults }); | ||
| expect(output).not.toContain("eyJzdWIiOiIxMjM0NTY3ODkwIn0"); | ||
| }); | ||
|
|
||
| it("masks Basic auth headers", () => { | ||
| const input = "Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ="; | ||
| const output = redactSensitiveText(input, { mode: "tools", patterns: defaults }); | ||
| expect(output).not.toContain("dXNlcm5hbWU6cGFzc3dvcmQ="); | ||
| }); | ||
|
|
||
| it("masks X-OpenClaw-Token headers", () => { | ||
| const input = 'X-OpenClaw-Token: oc_abcdef1234567890ghijklmn'; | ||
| const output = redactSensitiveText(input, { mode: "tools", patterns: defaults }); | ||
| expect(output).not.toContain("oc_abcdef1234567890ghijklmn"); | ||
| }); | ||
|
|
||
| it("masks x-pomerium-jwt-assertion headers", () => { | ||
| const jwt = | ||
| "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyQGV4YW1wbGUuY29tIn0.abc123def456ghi789jkl"; | ||
| const input = `x-pomerium-jwt-assertion: ${jwt}`; | ||
| const output = redactSensitiveText(input, { mode: "tools", patterns: defaults }); | ||
| expect(output).not.toContain("eyJzdWIiOiJ1c2VyQGV4YW1wbGUuY29tIn0"); | ||
| }); |
There was a problem hiding this comment.
Tests placed in wrong describe block; JWT test doesn't isolate the new pattern
All four new tests call redactSensitiveText but are nested inside describe("redactSensitiveLines", ...). They should live in the describe("redactSensitiveText", ...) block above (or a new dedicated block).
Additionally, the "masks generic JWT tokens" test uses Authorization: Bearer ${jwt} as input. This string is already matched by the pre-existing Bearer pattern (Authorization\s*[:=]\s*Bearer\s+...), so the test never actually exercises the new eyJ… JWT pattern. A standalone JWT (e.g. in a log line without a Bearer prefix) would better isolate the new pattern:
// tests the new eyJ JWT pattern directly
const input = `x-pomerium-jwt-assertion: ${jwt}`;
// or simply
const input = `some log line: jwt=${jwt}`;Prompt To Fix With AI
This is a comment left during a code review.
Path: src/logging/redact.test.ts
Line: 212-238
Comment:
**Tests placed in wrong describe block; JWT test doesn't isolate the new pattern**
All four new tests call `redactSensitiveText` but are nested inside `describe("redactSensitiveLines", ...)`. They should live in the `describe("redactSensitiveText", ...)` block above (or a new dedicated block).
Additionally, the `"masks generic JWT tokens"` test uses `Authorization: Bearer ${jwt}` as input. This string is already matched by the pre-existing Bearer pattern (`Authorization\s*[:=]\s*Bearer\s+...`), so the test never actually exercises the new `eyJ…` JWT pattern. A standalone JWT (e.g. in a log line without a `Bearer` prefix) would better isolate the new pattern:
```ts
// tests the new eyJ JWT pattern directly
const input = `x-pomerium-jwt-assertion: ${jwt}`;
// or simply
const input = `some log line: jwt=${jwt}`;
```
How can I resolve this? If you propose a fix, please make it concise.|
Codex review: needs real behavior proof before merge. Summary Reproducibility: yes. at source level with high confidence. Real behavior proof Next step before merge Security Review findings
Review detailsBest possible solution: Amend this PR or land an equivalent narrow patch so shared defaults fully redact raw Basic auth and named security headers, preserve current JWT coverage, and prove the Do we have a high-confidence way to reproduce the issue? Yes, at source level with high confidence. Is this the best way to solve the issue? No, not as written. The shared default redactor is the right layer, but the Basic auth pattern needs to cover valid short and padded Base64 credentials and the tests should isolate standalone JWT plus line/log-tail behavior. Full review comments:
Overall correctness: patch is incorrect Security concerns:
Acceptance criteria:
What I checked:
Likely related people:
Remaining risk / open question:
Codex review notes: model gpt-5.5, reasoning high; reviewed against 2eee70e0a64b. |
|
Codex review: needs maintainer review before merge. What this changes: The PR adds default log redaction regexes and tests for generic JWTs, Basic auth headers, Maintainer follow-up before merge: This is a valid open contributor PR for credential redaction, but it touches secret-leak prevention and needs maintainer review plus a small contributor or maintainer amendment rather than an autonomous replacement lane. Review detailsBest possible solution: Keep this PR as the implementation candidate for the linked redaction bug, but amend it so the shared default patterns fully cover padded Basic auth, standalone JWTs, and the named security headers, with focused tests for Acceptance criteria:
What I checked:
Likely related people:
Remaining risk / open question:
Codex review notes: model gpt-5.5, reasoning high; reviewed against acae48b790fa. |
|
Thanks for the focused fix. I landed a repaired equivalent on main in #82690 / e06782d, with contributor credit preserved. What changed from this PR before landing:
Proof: focused Vitest passed after final rebase (8 files / 348 tests), and Blacksmith Testbox through Crabbox passed |
Fix logs.tail credential-header redaction and JSON-mode gateway transport errors.\n\nFixes openclaw#66832.\nFixes openclaw#79108.\nSupersedes openclaw#67041.\nSupersedes openclaw#79233.\n\nCo-authored-by: Mil Wang <mingjwan@microsoft.com>\nCo-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Fix logs.tail credential-header redaction and JSON-mode gateway transport errors.\n\nFixes openclaw#66832.\nFixes openclaw#79108.\nSupersedes openclaw#67041.\nSupersedes openclaw#79233.\n\nCo-authored-by: Mil Wang <mingjwan@microsoft.com>\nCo-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Fix logs.tail credential-header redaction and JSON-mode gateway transport errors.\n\nFixes openclaw#66832.\nFixes openclaw#79108.\nSupersedes openclaw#67041.\nSupersedes openclaw#79233.\n\nCo-authored-by: Mil Wang <mingjwan@microsoft.com>\nCo-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Fix logs.tail credential-header redaction and JSON-mode gateway transport errors.\n\nFixes openclaw#66832.\nFixes openclaw#79108.\nSupersedes openclaw#67041.\nSupersedes openclaw#79233.\n\nCo-authored-by: Mil Wang <mingjwan@microsoft.com>\nCo-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Fix logs.tail credential-header redaction and JSON-mode gateway transport errors.\n\nFixes openclaw#66832.\nFixes openclaw#79108.\nSupersedes openclaw#67041.\nSupersedes openclaw#79233.\n\nCo-authored-by: Mil Wang <mingjwan@microsoft.com>\nCo-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Fix logs.tail credential-header redaction and JSON-mode gateway transport errors.\n\nFixes openclaw#66832.\nFixes openclaw#79108.\nSupersedes openclaw#67041.\nSupersedes openclaw#79233.\n\nCo-authored-by: Mil Wang <mingjwan@microsoft.com>\nCo-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Fix logs.tail credential-header redaction and JSON-mode gateway transport errors.\n\nFixes openclaw#66832.\nFixes openclaw#79108.\nSupersedes openclaw#67041.\nSupersedes openclaw#79233.\n\nCo-authored-by: Mil Wang <mingjwan@microsoft.com>\nCo-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Fix logs.tail credential-header redaction and JSON-mode gateway transport errors.\n\nFixes openclaw#66832.\nFixes openclaw#79108.\nSupersedes openclaw#67041.\nSupersedes openclaw#79233.\n\nCo-authored-by: Mil Wang <mingjwan@microsoft.com>\nCo-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Fix logs.tail credential-header redaction and JSON-mode gateway transport errors.\n\nFixes openclaw#66832.\nFixes openclaw#79108.\nSupersedes openclaw#67041.\nSupersedes openclaw#79233.\n\nCo-authored-by: Mil Wang <mingjwan@microsoft.com>\nCo-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Fix logs.tail credential-header redaction and JSON-mode gateway transport errors.\n\nFixes openclaw#66832.\nFixes openclaw#79108.\nSupersedes openclaw#67041.\nSupersedes openclaw#79233.\n\nCo-authored-by: Mil Wang <mingjwan@microsoft.com>\nCo-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Fix logs.tail credential-header redaction and JSON-mode gateway transport errors.\n\nFixes openclaw#66832.\nFixes openclaw#79108.\nSupersedes openclaw#67041.\nSupersedes openclaw#79233.\n\nCo-authored-by: Mil Wang <mingjwan@microsoft.com>\nCo-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Fix logs.tail credential-header redaction and JSON-mode gateway transport errors.\n\nFixes openclaw#66832.\nFixes openclaw#79108.\nSupersedes openclaw#67041.\nSupersedes openclaw#79233.\n\nCo-authored-by: Mil Wang <mingjwan@microsoft.com>\nCo-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Summary
\logs.tail\ redaction missed several credential formats that could leak secrets to \operator.read\ clients.
Changes
Added redaction patterns for:
Tests
Added 4 test cases in
edact.test.ts\ covering all new patterns.
Fixes #66832