[WRONG BRANCH] fix(oauth): redact secrets in structured OAuth event logs - #185
[WRONG BRANCH] fix(oauth): redact secrets in structured OAuth event logs#185luvs01 wants to merge 1 commit into
Conversation
|
This pull request currently targets @luvs01 Please retarget this PR to Its title has been prefixed with This pull request is being kept as a draft automatically. Once every issue above is resolved, it will be marked ready for review again. |
📝 WalkthroughWalkthroughOAuth logging now redacts assembled messages before output. The forbidden OAuth field list includes ChangesOAuth logging sanitization
Estimated code review effort: 2 (Simple) | ~10 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/oauth/log.ts`:
- Line 49: Update the OAuth diagnostic sanitization around redactSecretString
and isForbiddenFieldKey to redact code_verifier= values and reject normalized
field keys ending in _code_verifier, preventing PKCE verifiers from reaching
console.info. Add regression coverage for both direct verifier redaction and
forbidden suffixed keys in tests/oauth-log.test.ts.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: cedef752-387c-4a1f-9ba7-e5742157054e
📒 Files selected for processing (2)
src/oauth/log.tstests/oauth-log.test.ts
| parts.push(`${key}=${String(value)}`); | ||
| } | ||
| console.info(parts.join(" ")); | ||
| console.info(redactSecretString(parts.join(" "))); |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n -C 12 'SECRET_VALUE_PATTERNS|maskCredentialHeaders|redactSecretString' src/lib/redact.ts
rg -n -C 4 'logOAuthEvent|code_verifier|codeVerifier|code-verifier|oauth_code_verifier|oauthCodeVerifier' src testsRepository: luvs01/opencodex
Length of output: 17129
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- src/oauth/log.ts ---'
cat -n src/oauth/log.ts | sed -n '1,90p'
printf '%s\n' '--- oauth log tests ---'
cat -n tests/oauth-log.test.ts | sed -n '1,140p'
printf '%s\n' '--- all logOAuthEvent call sites ---'
rg -n -C 3 'logOAuthEvent\s*\(' src testsRepository: luvs01/opencodex
Length of output: 9604
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- redaction framing rules ---'
cat -n src/lib/redact.ts | sed -n '240,445p'
printf '%s\n' '--- redaction tests for OAuth and verifier-shaped values ---'
rg -n -C 5 'redactSecretString|code_verifier|code-verifier|verifier|Bearer|api[_-]?key' tests src/lib/redact.ts
printf '%s\n' '--- standalone PKCE-pattern probe ---'
node - <<'JS'
const verifier = "A".repeat(43) + "._~-9";
const samples = [
`diagnostic: code_verifier=${verifier}`,
`diagnostic=code_verifier=${verifier}`,
`oauth_code_verifier=${verifier}`,
`code-verifier=${verifier}`,
];
const patterns = [
[/\b(Bearer)([^\S\r\n]+)[A-Za-z0-9._~+/=-]{8,}\b/gi, "bearer"],
[/\b(sk-[A-Za-z0-9][A-Za-z0-9._-]{6,})\b/g, "sk"],
[/\b(gh[pousr]_[A-Za-z0-9_]{8,}|github_pat_[A-Za-z0-9_]{20,})\b/g, "github"],
[/\btid=[A-Za-z0-9-]+(?:;[A-Za-z0-9_.-]+=[^;\s"']*)+(?::[A-Za-z0-9+/=_-]+)?/g, "copilot"],
[/\b((?:api[_-]?key|access[_-]?token|refresh[_-]?token|id[_-]?token|client[_-]?secret|refreshToken|accessToken|clientSecret|apiKey)=)([^&\s"',;]+)/gi, "key-value"],
];
for (const sample of samples) {
const matches = patterns
.filter(([pattern]) => pattern.test(sample))
.map(([, name]) => name);
for (const [pattern] of patterns) pattern.lastIndex = 0;
console.log(JSON.stringify({ sample, matches }));
}
JSRepository: luvs01/opencodex
Length of output: 50373
🏁 Script executed:
#!/bin/bash
set -euo pipefail
cat -n src/lib/redact.ts | sed -n '240,445p'
printf '%s\n' '--- standalone probe output ---'
node - <<'JS'
const verifier = "A".repeat(43) + "._~-9";
const samples = [
`diagnostic: code_verifier=${verifier}`,
`diagnostic=code_verifier=${verifier}`,
`oauth_code_verifier=${verifier}`,
`code-verifier=${verifier}`,
];
const patterns = [
[/\b(Bearer)([^\S\r\n]+)[A-Za-z0-9._~+/=-]{8,}\b/gi, "bearer"],
[/\b(sk-[A-Za-z0-9][A-Za-z0-9._-]{6,})\b/g, "sk"],
[/\b(gh[pousr]_[A-Za-z0-9_]{8,}|github_pat_[A-Za-z0-9_]{20,})\b/g, "github"],
[/\btid=[A-Za-z0-9-]+(?:;[A-Za-z0-9_.-]+=[^;\s"']*)+(?::[A-Za-z0-9+/=_-]+)?/g, "copilot"],
[/\b((?:api[_-]?key|access[_-]?token|refresh[_-]?token|id[_-]?token|client[_-]?secret|refreshToken|accessToken|clientSecret|apiKey)=)([^&\s"',;]+)/gi, "key-value"],
];
for (const sample of samples) {
const matches = [];
for (const [pattern, name] of patterns) {
pattern.lastIndex = 0;
if (pattern.test(sample)) matches.push(name);
}
console.log(JSON.stringify({ sample, matches }));
}
JSRepository: luvs01/opencodex
Length of output: 12325
Redact PKCE verifiers embedded in OAuth diagnostics.
redactSecretString does not match code_verifier= values, and isForbiddenFieldKey does not reject keys such as oauth_code_verifier. A PKCE verifier can therefore reach console.info through an otherwise safe field. Add a verifier-specific redaction rule and reject normalized keys ending in _code_verifier. Add regression tests for both cases in tests/oauth-log.test.ts.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/oauth/log.ts` at line 49, Update the OAuth diagnostic sanitization around
redactSecretString and isForbiddenFieldKey to redact code_verifier= values and
reject normalized field keys ending in _code_verifier, preventing PKCE verifiers
from reaching console.info. Add regression coverage for both direct verifier
redaction and forbidden suffixed keys in tests/oauth-log.test.ts.
Source: Path instructions
Motivation
access_token,refresh_token,id_token,client_secret) or token-shaped values stored under benign keys.Description
redactSecretStringon the assembled log line before callingconsole.infoinsrc/oauth/log.ts.code_verifieralongside existing token/secret names and rely on the existing normalization to catch camelCase/snake_case/kebab-case field names.partsstring throughredactSecretStringinstead of writingparts.join(" ")directly.tests/oauth-log.test.tsto assert suppression ofcode_verifierand that token-shaped values (Bearer tokens,sk-keys) embedded under otherwise safe keys are redacted.Testing
bun test tests/oauth-log.test.ts, which passed (3 tests, 0 failures).bun run typecheck, which passed with no type errors reported.bun run privacy:scan, which passed and did not flag new privacy leaks.bun run test; the OAuth-specific changes are green but the full test run surfaced unrelated environment-sensitive failures in other tests (tests/codex-sync-api.test.tsandtests/cli-help.test.ts) that are not caused by this change.Codex Task
Summary by CodeRabbit
code_verifierfields.