mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
fix(core): Do not send credentials to browser console (#5031)
This commit is contained in:
parent
a229788d4b
commit
afc529799d
packages/nodes-base/nodes/HttpRequest
|
@ -1,4 +1,9 @@
|
|||
import { INodeExecutionData, IOAuth2Options } from 'n8n-workflow';
|
||||
import { IDataObject, INodeExecutionData, IOAuth2Options } from 'n8n-workflow';
|
||||
import { OptionsWithUri } from 'request-promise-native';
|
||||
|
||||
export type IAuthDataSanitizeKeys = {
|
||||
[key: string]: string[];
|
||||
};
|
||||
|
||||
export const replaceNullValues = (item: INodeExecutionData) => {
|
||||
if (item.json === null) {
|
||||
|
@ -7,6 +12,37 @@ export const replaceNullValues = (item: INodeExecutionData) => {
|
|||
return item;
|
||||
};
|
||||
|
||||
export function sanitizeUiMessage(request: OptionsWithUri, authDataKeys: IAuthDataSanitizeKeys) {
|
||||
let sendRequest = request as unknown as IDataObject;
|
||||
|
||||
// Protect browser from sending large binary data
|
||||
if (Buffer.isBuffer(sendRequest.body) && sendRequest.body.length > 250000) {
|
||||
sendRequest = {
|
||||
...request,
|
||||
body: `Binary data got replaced with this text. Original was a Buffer with a size of ${request.body.length} byte.`,
|
||||
};
|
||||
}
|
||||
|
||||
// Remove credential information
|
||||
for (const requestProperty of Object.keys(authDataKeys)) {
|
||||
sendRequest = {
|
||||
...sendRequest,
|
||||
[requestProperty]: Object.keys(sendRequest[requestProperty] as object).reduce(
|
||||
// eslint-disable-next-line @typescript-eslint/no-loop-func
|
||||
(acc: IDataObject, curr) => {
|
||||
acc[curr] = authDataKeys[requestProperty].includes(curr)
|
||||
? '** hidden **'
|
||||
: (sendRequest[requestProperty] as IDataObject)[curr];
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
return sendRequest;
|
||||
}
|
||||
|
||||
export const getOAuth2AdditionalParameters = (nodeCredentialType: string) => {
|
||||
const oAuth2Options: { [credentialType: string]: IOAuth2Options } = {
|
||||
bitlyOAuth2Api: {
|
||||
|
|
|
@ -13,7 +13,7 @@ import {
|
|||
} from 'n8n-workflow';
|
||||
|
||||
import { OptionsWithUri } from 'request';
|
||||
import { replaceNullValues } from '../GenericFunctions';
|
||||
import { IAuthDataSanitizeKeys, replaceNullValues, sanitizeUiMessage } from '../GenericFunctions';
|
||||
|
||||
interface OptionData {
|
||||
name: string;
|
||||
|
@ -914,21 +914,26 @@ export class HttpRequestV1 implements INodeType {
|
|||
requestOptions.headers['Content-Type'] = options.bodyContentCustomMimeType;
|
||||
}
|
||||
|
||||
const authDataKeys: IAuthDataSanitizeKeys = {};
|
||||
|
||||
// Add credentials if any are set
|
||||
if (httpBasicAuth !== undefined) {
|
||||
requestOptions.auth = {
|
||||
user: httpBasicAuth.user as string,
|
||||
pass: httpBasicAuth.password as string,
|
||||
};
|
||||
authDataKeys.auth = ['pass'];
|
||||
}
|
||||
if (httpHeaderAuth !== undefined) {
|
||||
requestOptions.headers![httpHeaderAuth.name as string] = httpHeaderAuth.value;
|
||||
authDataKeys.headers = [httpHeaderAuth.name as string];
|
||||
}
|
||||
if (httpQueryAuth !== undefined) {
|
||||
if (!requestOptions.qs) {
|
||||
requestOptions.qs = {};
|
||||
}
|
||||
requestOptions.qs[httpQueryAuth.name as string] = httpQueryAuth.value;
|
||||
authDataKeys.qs = [httpQueryAuth.name as string];
|
||||
}
|
||||
if (httpDigestAuth !== undefined) {
|
||||
requestOptions.auth = {
|
||||
|
@ -936,6 +941,7 @@ export class HttpRequestV1 implements INodeType {
|
|||
pass: httpDigestAuth.password as string,
|
||||
sendImmediately: false,
|
||||
};
|
||||
authDataKeys.auth = ['pass'];
|
||||
}
|
||||
|
||||
if (requestOptions.headers!.accept === undefined) {
|
||||
|
@ -951,15 +957,7 @@ export class HttpRequestV1 implements INodeType {
|
|||
}
|
||||
|
||||
try {
|
||||
let sendRequest: any = requestOptions;
|
||||
// Protect browser from sending large binary data
|
||||
if (Buffer.isBuffer(sendRequest.body) && sendRequest.body.length > 250000) {
|
||||
sendRequest = {
|
||||
...requestOptions,
|
||||
body: `Binary data got replaced with this text. Original was a Buffer with a size of ${requestOptions.body.length} byte.`,
|
||||
};
|
||||
}
|
||||
this.sendMessageToUI(sendRequest);
|
||||
this.sendMessageToUI(sanitizeUiMessage(requestOptions, authDataKeys));
|
||||
} catch (e) {}
|
||||
|
||||
if (oAuth1Api) {
|
||||
|
|
|
@ -11,7 +11,12 @@ import {
|
|||
} from 'n8n-workflow';
|
||||
|
||||
import { OptionsWithUri } from 'request';
|
||||
import { getOAuth2AdditionalParameters, replaceNullValues } from '../GenericFunctions';
|
||||
import {
|
||||
getOAuth2AdditionalParameters,
|
||||
IAuthDataSanitizeKeys,
|
||||
replaceNullValues,
|
||||
sanitizeUiMessage,
|
||||
} from '../GenericFunctions';
|
||||
|
||||
interface OptionData {
|
||||
name: string;
|
||||
|
@ -948,21 +953,26 @@ export class HttpRequestV2 implements INodeType {
|
|||
requestOptions.headers['Content-Type'] = options.bodyContentCustomMimeType;
|
||||
}
|
||||
|
||||
const authDataKeys: IAuthDataSanitizeKeys = {};
|
||||
|
||||
// Add credentials if any are set
|
||||
if (httpBasicAuth !== undefined) {
|
||||
requestOptions.auth = {
|
||||
user: httpBasicAuth.user as string,
|
||||
pass: httpBasicAuth.password as string,
|
||||
};
|
||||
authDataKeys.auth = ['pass'];
|
||||
}
|
||||
if (httpHeaderAuth !== undefined) {
|
||||
requestOptions.headers![httpHeaderAuth.name as string] = httpHeaderAuth.value;
|
||||
authDataKeys.headers = [httpHeaderAuth.name as string];
|
||||
}
|
||||
if (httpQueryAuth !== undefined) {
|
||||
if (!requestOptions.qs) {
|
||||
requestOptions.qs = {};
|
||||
}
|
||||
requestOptions.qs[httpQueryAuth.name as string] = httpQueryAuth.value;
|
||||
authDataKeys.qs = [httpQueryAuth.name as string];
|
||||
}
|
||||
if (httpDigestAuth !== undefined) {
|
||||
requestOptions.auth = {
|
||||
|
@ -970,6 +980,7 @@ export class HttpRequestV2 implements INodeType {
|
|||
pass: httpDigestAuth.password as string,
|
||||
sendImmediately: false,
|
||||
};
|
||||
authDataKeys.auth = ['pass'];
|
||||
}
|
||||
|
||||
if (requestOptions.headers!.accept === undefined) {
|
||||
|
@ -985,15 +996,7 @@ export class HttpRequestV2 implements INodeType {
|
|||
}
|
||||
|
||||
try {
|
||||
let sendRequest: any = requestOptions;
|
||||
// Protect browser from sending large binary data
|
||||
if (Buffer.isBuffer(sendRequest.body) && sendRequest.body.length > 250000) {
|
||||
sendRequest = {
|
||||
...requestOptions,
|
||||
body: `Binary data got replaced with this text. Original was a Buffer with a size of ${requestOptions.body.length} byte.`,
|
||||
};
|
||||
}
|
||||
this.sendMessageToUI(sendRequest);
|
||||
this.sendMessageToUI(sanitizeUiMessage(requestOptions, authDataKeys));
|
||||
} catch (e) {}
|
||||
|
||||
if (authentication === 'genericCredentialType' || authentication === 'none') {
|
||||
|
|
|
@ -17,7 +17,9 @@ import { OptionsWithUri } from 'request-promise-native';
|
|||
import {
|
||||
binaryContentTypes,
|
||||
getOAuth2AdditionalParameters,
|
||||
IAuthDataSanitizeKeys,
|
||||
replaceNullValues,
|
||||
sanitizeUiMessage,
|
||||
} from '../GenericFunctions';
|
||||
export class HttpRequestV3 implements INodeType {
|
||||
description: INodeTypeDescription;
|
||||
|
@ -1208,21 +1210,26 @@ export class HttpRequestV3 implements INodeType {
|
|||
requestOptions.headers['Content-Type'] = rawContentType;
|
||||
}
|
||||
|
||||
const authDataKeys: IAuthDataSanitizeKeys = {};
|
||||
|
||||
// Add credentials if any are set
|
||||
if (httpBasicAuth !== undefined) {
|
||||
requestOptions.auth = {
|
||||
user: httpBasicAuth.user as string,
|
||||
pass: httpBasicAuth.password as string,
|
||||
};
|
||||
authDataKeys.auth = ['pass'];
|
||||
}
|
||||
if (httpHeaderAuth !== undefined) {
|
||||
requestOptions.headers![httpHeaderAuth.name as string] = httpHeaderAuth.value;
|
||||
authDataKeys.headers = [httpHeaderAuth.name as string];
|
||||
}
|
||||
if (httpQueryAuth !== undefined) {
|
||||
if (!requestOptions.qs) {
|
||||
requestOptions.qs = {};
|
||||
}
|
||||
requestOptions.qs[httpQueryAuth.name as string] = httpQueryAuth.value;
|
||||
authDataKeys.qs = [httpQueryAuth.name as string];
|
||||
}
|
||||
if (httpDigestAuth !== undefined) {
|
||||
requestOptions.auth = {
|
||||
|
@ -1230,6 +1237,7 @@ export class HttpRequestV3 implements INodeType {
|
|||
pass: httpDigestAuth.password as string,
|
||||
sendImmediately: false,
|
||||
};
|
||||
authDataKeys.auth = ['pass'];
|
||||
}
|
||||
|
||||
if (requestOptions.headers!.accept === undefined) {
|
||||
|
@ -1245,15 +1253,7 @@ export class HttpRequestV3 implements INodeType {
|
|||
}
|
||||
|
||||
try {
|
||||
let sendRequest: any = requestOptions;
|
||||
// Protect browser from sending large binary data
|
||||
if (Buffer.isBuffer(sendRequest.body) && sendRequest.body.length > 250000) {
|
||||
sendRequest = {
|
||||
...requestOptions,
|
||||
body: `Binary data got replaced with this text. Original was a Buffer with a size of ${requestOptions.body.length} byte.`,
|
||||
};
|
||||
}
|
||||
this.sendMessageToUI(sendRequest);
|
||||
this.sendMessageToUI(sanitizeUiMessage(requestOptions, authDataKeys));
|
||||
} catch (e) {}
|
||||
|
||||
if (authentication === 'genericCredentialType' || authentication === 'none') {
|
||||
|
|
Loading…
Reference in a new issue