mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-16 04:18:05 +00:00
Merge pull request #1307 from kaitranntt/codex/propose-fix-for-oauth-log-redaction-issue
fix(cliproxy): redact token-like OAuth trace snippets
This commit is contained in:
@@ -51,6 +51,40 @@ describe('redactString', () => {
|
||||
test('empty input passthrough', () => {
|
||||
expect(redactString('')).toBe('');
|
||||
});
|
||||
|
||||
test('redacts JSON-style token payloads in plain strings', () => {
|
||||
const out = redactString(
|
||||
'{"access_token":"AT_SECRET","refresh_token":"RT_SECRET","token":"TOKEN_SECRET"}'
|
||||
);
|
||||
expect(out).not.toContain('AT_SECRET');
|
||||
expect(out).not.toContain('RT_SECRET');
|
||||
expect(out).not.toContain('TOKEN_SECRET');
|
||||
expect(out).toContain(REDACTED_PLACEHOLDER);
|
||||
});
|
||||
|
||||
test('preserves JSON-style separator spacing while redacting token payloads', () => {
|
||||
const out = redactString('{"access_token" : "AT_SECRET"}');
|
||||
expect(out).not.toContain('AT_SECRET');
|
||||
expect(out).toContain(`"access_token" : "${REDACTED_PLACEHOLDER}"`);
|
||||
});
|
||||
|
||||
test('redacts line-leading key/value formats', () => {
|
||||
const out = redactString(
|
||||
'access_token=AT_SECRET refresh_token=RT_SECRET client_secret: CS_SECRET'
|
||||
);
|
||||
expect(out).not.toContain('AT_SECRET');
|
||||
expect(out).not.toContain('RT_SECRET');
|
||||
expect(out).not.toContain('CS_SECRET');
|
||||
expect(out).toContain(`access_token=${REDACTED_PLACEHOLDER}`);
|
||||
expect(out).toContain(`refresh_token=${REDACTED_PLACEHOLDER}`);
|
||||
expect(out).toContain(`client_secret: ${REDACTED_PLACEHOLDER}`);
|
||||
});
|
||||
|
||||
test('preserves URL-style suffixes in line-leading key/value snippets', () => {
|
||||
const out = redactString('access_token=AT_SECRET&keep=1');
|
||||
expect(out).not.toContain('AT_SECRET');
|
||||
expect(out).toBe(`access_token=${REDACTED_PLACEHOLDER}&keep=1`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('redactUrl', () => {
|
||||
|
||||
@@ -40,12 +40,34 @@ const QUERY_PARAM_REGEX = new RegExp(
|
||||
|
||||
const BEARER_REGEX = /Bearer\s+[A-Za-z0-9._\-~+/=]+/gi;
|
||||
|
||||
const KV_SEPARATORS = String.raw`(?:=|:)`;
|
||||
const VALUE_FRAGMENT = String.raw`[^\s,;&\]}\"']+`;
|
||||
const STRING_KV_KEYS = [...SENSITIVE_QUERY_KEYS, 'token'].filter((key) => key !== 'authorization');
|
||||
const SENSITIVE_KEY_GROUP = `(${STRING_KV_KEYS.join('|')})`;
|
||||
const LEADING_KV_REGEX = new RegExp(
|
||||
String.raw`(^|\s)${SENSITIVE_KEY_GROUP}(\s*${KV_SEPARATORS}\s*)${VALUE_FRAGMENT}`,
|
||||
'gi'
|
||||
);
|
||||
const QUOTED_JSON_KV_REGEX = new RegExp(
|
||||
String.raw`([\"'])${SENSITIVE_KEY_GROUP}\1(\s*:\s*)([\"'])(?:\\.|(?!\4).)*?\4`,
|
||||
'gi'
|
||||
);
|
||||
|
||||
/** Redact sensitive query-param values inside any string. Idempotent. */
|
||||
export function redactString(s: string): string {
|
||||
if (!s) return s;
|
||||
return s
|
||||
.replace(QUERY_PARAM_REGEX, (_full, key) => `${key}=${REDACTED}`)
|
||||
.replace(BEARER_REGEX, `Bearer ${REDACTED}`);
|
||||
.replace(BEARER_REGEX, `Bearer ${REDACTED}`)
|
||||
.replace(
|
||||
QUOTED_JSON_KV_REGEX,
|
||||
(_full, quoteKey, key, separator, quoteVal) =>
|
||||
`${quoteKey}${key}${quoteKey}${separator}${quoteVal}${REDACTED}${quoteVal}`
|
||||
)
|
||||
.replace(
|
||||
LEADING_KV_REGEX,
|
||||
(_full, prefix, key, separator) => `${prefix}${key}${separator}${REDACTED}`
|
||||
);
|
||||
}
|
||||
|
||||
/** Redact a parsed URL by name; returns redacted href or original on parse error. */
|
||||
|
||||
Reference in New Issue
Block a user