mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-11 21:07:28 -08:00
fix(HTTP Request Node): Sanitize authorization headers (#10607)
This commit is contained in:
parent
c4eb3746d7
commit
405c55a1f7
|
@ -88,7 +88,24 @@ export function sanitizeUiMessage(
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
const HEADER_BLOCKLIST = new Set([
|
||||||
|
'authorization',
|
||||||
|
'x-api-key',
|
||||||
|
'x-auth-token',
|
||||||
|
'cookie',
|
||||||
|
'proxy-authorization',
|
||||||
|
'sslclientcert',
|
||||||
|
]);
|
||||||
|
|
||||||
|
const headers = sendRequest.headers as IDataObject;
|
||||||
|
|
||||||
|
if (headers) {
|
||||||
|
for (const headerName of Object.keys(headers)) {
|
||||||
|
if (HEADER_BLOCKLIST.has(headerName.toLowerCase())) {
|
||||||
|
headers[headerName] = REDACTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (secrets && secrets.length > 0) {
|
if (secrets && secrets.length > 0) {
|
||||||
return redact(sendRequest, secrets);
|
return redact(sendRequest, secrets);
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,5 +136,68 @@ describe('HTTP Node Utils', () => {
|
||||||
uri: 'https://example.com',
|
uri: 'https://example.com',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const headersToTest = [
|
||||||
|
'authorization',
|
||||||
|
'x-api-key',
|
||||||
|
'x-auth-token',
|
||||||
|
'cookie',
|
||||||
|
'proxy-authorization',
|
||||||
|
'sslclientcert',
|
||||||
|
];
|
||||||
|
|
||||||
|
headersToTest.forEach((header) => {
|
||||||
|
it(`should redact the ${header} header when the key is lowercase`, () => {
|
||||||
|
const requestOptions: IRequestOptions = {
|
||||||
|
method: 'POST',
|
||||||
|
uri: 'https://example.com',
|
||||||
|
body: { sessionToken: 'secret', other: 'foo' },
|
||||||
|
headers: { [header]: 'some-sensitive-token', other: 'foo' },
|
||||||
|
auth: { user: 'user', password: 'secret' },
|
||||||
|
};
|
||||||
|
|
||||||
|
const sanitizedRequest = sanitizeUiMessage(requestOptions, {});
|
||||||
|
|
||||||
|
expect(sanitizedRequest.headers).toEqual({ [header]: REDACTED, other: 'foo' });
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should redact the ${header} header when the key is uppercase`, () => {
|
||||||
|
const requestOptions: IRequestOptions = {
|
||||||
|
method: 'POST',
|
||||||
|
uri: 'https://example.com',
|
||||||
|
body: { sessionToken: 'secret', other: 'foo' },
|
||||||
|
headers: { [header.toUpperCase()]: 'some-sensitive-token', other: 'foo' },
|
||||||
|
auth: { user: 'user', password: 'secret' },
|
||||||
|
};
|
||||||
|
|
||||||
|
const sanitizedRequest = sanitizeUiMessage(requestOptions, {});
|
||||||
|
|
||||||
|
expect(sanitizedRequest.headers).toEqual({
|
||||||
|
[header.toUpperCase()]: REDACTED,
|
||||||
|
other: 'foo',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should leave headers unchanged if Authorization header is not present', () => {
|
||||||
|
const requestOptions: IRequestOptions = {
|
||||||
|
method: 'POST',
|
||||||
|
uri: 'https://example.com',
|
||||||
|
body: { sessionToken: 'secret', other: 'foo' },
|
||||||
|
headers: { other: 'foo' },
|
||||||
|
auth: { user: 'user', password: 'secret' },
|
||||||
|
};
|
||||||
|
const sanitizedRequest = sanitizeUiMessage(requestOptions, {});
|
||||||
|
|
||||||
|
expect(sanitizedRequest.headers).toEqual({ other: 'foo' });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle case when headers are undefined', () => {
|
||||||
|
const requestOptions: IRequestOptions = {};
|
||||||
|
|
||||||
|
const sanitizedRequest = sanitizeUiMessage(requestOptions, {});
|
||||||
|
|
||||||
|
expect(sanitizedRequest.headers).toBeUndefined();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue