fix(adapter-utils): consume a line continuation inside a quoted header value
A backslash-newline continuation inside a double-quoted header argument ended the quoted match, so the unquoted fallback redacted only the part of the credential before the continuation. The double-quoted branch now treats the continuation as part of the value, with LF and CRLF line endings. Claude-Session: https://claude.ai/code/session_01RYigf3eMFJjey9iKRApPGE
This commit is contained in:
parent
d273feaa7f
commit
da8225744a
|
|
@ -286,6 +286,20 @@ describe("redactCommandText header secrets", () => {
|
|||
);
|
||||
});
|
||||
|
||||
it("redacts across a backslash-newline continuation inside a double-quoted value", () => {
|
||||
// A shell line continuation inside double quotes is part of the argument.
|
||||
const input = 'curl -H "X-API-Key: abc\\\ndef" https://example.test';
|
||||
const output = redactCommandText(input);
|
||||
expect(output).not.toContain("def");
|
||||
expect(output).toBe(
|
||||
`curl -H "X-API-Key: ${REDACTED_COMMAND_TEXT_VALUE}" https://example.test`,
|
||||
);
|
||||
const crlf = 'curl -H "X-API-Key: abc\\\r\ndef" https://example.test';
|
||||
expect(redactCommandText(crlf)).toBe(
|
||||
`curl -H "X-API-Key: ${REDACTED_COMMAND_TEXT_VALUE}" https://example.test`,
|
||||
);
|
||||
});
|
||||
|
||||
it("redacts a backslash inside a single-quoted header value", () => {
|
||||
// A shell single quote has no escapes, so the backslash is part of the value.
|
||||
const input = String.raw`curl -H 'X-API-Key: abc\def' https://example.test`;
|
||||
|
|
|
|||
|
|
@ -47,7 +47,8 @@ const COMMAND_AUTHORIZATION_BEARER_RE =
|
|||
//
|
||||
// Each branch treats the backslash the way its quoting context does. A
|
||||
// double-quoted value consumes escape pairs, so an escaped quote inside the
|
||||
// argument (`"X-API-Key: abc\"def"`) does not end the value early. Its opening
|
||||
// argument (`"X-API-Key: abc\"def"`) does not end the value early, and neither
|
||||
// does a backslash-newline line continuation. Its opening
|
||||
// quote must itself be unescaped, which keeps the branch off a serialized
|
||||
// diagnostic such as `\"X-API-Key: ...\"`, where the closing `\"` must survive.
|
||||
// A single-quoted value takes a backslash literally, because a shell single
|
||||
|
|
@ -95,7 +96,7 @@ const COMMAND_SECRET_HEADER_UNQUOTED_VALUE_PATTERN =
|
|||
"`" +
|
||||
String.raw`]+)`;
|
||||
const COMMAND_SECRET_HEADER_RE = new RegExp(
|
||||
String.raw`(?<!\\)("${COMMAND_SECRET_HEADER_PREFIX_PATTERN})(?:\\.|[^\s"\\])(?:\\.|[^"\\\r\n])*(")` +
|
||||
String.raw`(?<!\\)("${COMMAND_SECRET_HEADER_PREFIX_PATTERN})(?:\\.|[^\s"\\])(?:\\\r?\n|\\.|[^"\\\r\n])*(")` +
|
||||
String.raw`|('${COMMAND_SECRET_HEADER_PREFIX_PATTERN})[^\s'][^'\r\n]*(')` +
|
||||
String.raw`|(\b${COMMAND_SECRET_HEADER_PREFIX_PATTERN})${COMMAND_SECRET_HEADER_UNQUOTED_VALUE_PATTERN}`,
|
||||
"gi",
|
||||
|
|
|
|||
Loading…
Reference in New Issue