Skip to content

Commit a7b7e64

Browse files
authored
Apply remaining changes
1 parent 108b93f commit a7b7e64

3 files changed

Lines changed: 39 additions & 6 deletions

File tree

src/services/secret-redactor.ts

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ const SECRET_QUERY_PARAMETER_NAMES = new Set([
3131
'sig',
3232
'subscription-key',
3333
]);
34+
const BEARER_TOKEN_PATTERN = /^(\s*Bearer)(\s+)(.*?)(\s*)$/i;
3435

3536
export interface PolicySecretFinding {
3637
location: string;
@@ -91,6 +92,29 @@ function shouldRedactLiteral(value: string): boolean {
9192
return !isApimNamedValueReference(trimmed);
9293
}
9394

95+
function redactAuthorizationHeaderValue(
96+
value: string
97+
): { redactedValue: string; wasRedacted: boolean } {
98+
const bearerMatch = BEARER_TOKEN_PATTERN.exec(value);
99+
if (bearerMatch) {
100+
const [, scheme, spacing, tokenValue, suffix] = bearerMatch;
101+
if (!shouldRedactLiteral(tokenValue)) {
102+
return { redactedValue: value, wasRedacted: false };
103+
}
104+
105+
return {
106+
redactedValue: `${scheme}${spacing}${REDACTION_MARKER}${suffix}`,
107+
wasRedacted: true,
108+
};
109+
}
110+
111+
if (!shouldRedactLiteral(value)) {
112+
return { redactedValue: value, wasRedacted: false };
113+
}
114+
115+
return { redactedValue: REDACTION_MARKER, wasRedacted: true };
116+
}
117+
94118
/**
95119
* Redact inline literal secrets in policy XML content.
96120
*/
@@ -114,12 +138,19 @@ export function redactPolicySecrets(
114138
return setHeaderBlock.replace(
115139
/(<value\b[^>]*>)([\s\S]*?)(<\/value>)/gi,
116140
(_full, openTag: string, value: string, closeTag: string) => {
117-
if (!shouldRedactLiteral(value)) {
141+
const shouldRedactHeaderValue = shouldRedactLiteral(value);
142+
const { redactedValue, wasRedacted } = headerName === 'authorization'
143+
? redactAuthorizationHeaderValue(value)
144+
: {
145+
redactedValue: shouldRedactHeaderValue ? REDACTION_MARKER : value,
146+
wasRedacted: shouldRedactHeaderValue,
147+
};
148+
if (!wasRedacted) {
118149
return `${openTag}${value}${closeTag}`;
119150
}
120151

121152
addFinding(`set-header[${headerName}]`);
122-
return `${openTag}${REDACTION_MARKER}${closeTag}`;
153+
return `${openTag}${redactedValue}${closeTag}`;
123154
}
124155
);
125156
});

tests/unit/services/api-product-extractor.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,8 +263,8 @@ describe('api-extractor', () => {
263263
});
264264

265265
it('should extract API policy and redact inline secrets', async () => {
266-
const policyContent = '<policies><inbound><set-header name="Authorization"><value>AUTH_LITERAL_VALUE</value></set-header></inbound></policies>';
267-
const redactedPolicy = `<policies><inbound><set-header name="Authorization"><value>${REDACTION_MARKER}</value></set-header></inbound></policies>`;
266+
const policyContent = '<policies><inbound><set-header name="Authorization"><value>Bearer TOKEN_LITERAL</value></set-header></inbound></policies>';
267+
const redactedPolicy = `<policies><inbound><set-header name="Authorization"><value>Bearer ${REDACTION_MARKER}</value></set-header></inbound></policies>`;
268268
const client = createMockClient({
269269
getResource: vi.fn().mockImplementation(async (_ctx: unknown, desc: ResourceDescriptor) => {
270270
if (desc.type === ResourceType.ApiPolicy) {

tests/unit/services/secret-redactor.test.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ describe('secret-redactor', () => {
114114
const basicAuthPolicy = `<authentication-basic username="user" ${passwordAttribute}="PWD_LITERAL" />`;
115115
const policyXml = `<policies>
116116
<inbound>
117-
<set-header name="Authorization"><value>AUTH_LITERAL_VALUE</value></set-header>
117+
<set-header name="Authorization"><value>Bearer TOKEN_LITERAL</value></set-header>
118+
<set-header name="Authorization"><value>Bearer {{jwt-token}}</value></set-header>
118119
<set-header name="api-key"><value>{{my-api-key}}</value></set-header>
119120
<set-query-parameter name="sig"><value>abc123</value></set-query-parameter>
120121
${basicAuthPolicy}
@@ -128,7 +129,8 @@ describe('secret-redactor', () => {
128129

129130
const { redactedContent, findings } = redactPolicySecrets(policyXml);
130131

131-
expect(redactedContent).toContain(`<set-header name="Authorization"><value>${REDACTION_MARKER}</value></set-header>`);
132+
expect(redactedContent).toContain(`<set-header name="Authorization"><value>Bearer ${REDACTION_MARKER}</value></set-header>`);
133+
expect(redactedContent).toContain('<set-header name="Authorization"><value>Bearer {{jwt-token}}</value></set-header>');
132134
expect(redactedContent).toContain('<set-header name="api-key"><value>{{my-api-key}}</value></set-header>');
133135
expect(redactedContent).toContain(`<set-query-parameter name="sig"><value>${REDACTION_MARKER}</value></set-query-parameter>`);
134136
expect(redactedContent).toContain('<authentication-basic username="user"');

0 commit comments

Comments
 (0)