mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 10:02:05 +00:00
fix(HTTP Request Node): Sanitize secrets of predefined credentials (#9612)
This commit is contained in:
@@ -1,16 +1,20 @@
|
||||
import type { SecureContextOptions } from 'tls';
|
||||
import type {
|
||||
ICredentialDataDecryptedObject,
|
||||
IDataObject,
|
||||
INodeExecutionData,
|
||||
INodeProperties,
|
||||
IOAuth2Options,
|
||||
IRequestOptions,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import set from 'lodash/set';
|
||||
import isPlainObject from 'lodash/isPlainObject';
|
||||
|
||||
import FormData from 'form-data';
|
||||
import type { HttpSslAuthCredentials } from './interfaces';
|
||||
import { formatPrivateKey } from '../../utils/utilities';
|
||||
import type { HttpSslAuthCredentials } from './interfaces';
|
||||
import get from 'lodash/get';
|
||||
|
||||
export type BodyParameter = {
|
||||
name: string;
|
||||
@@ -29,7 +33,33 @@ export const replaceNullValues = (item: INodeExecutionData) => {
|
||||
return item;
|
||||
};
|
||||
|
||||
export function sanitizeUiMessage(request: IRequestOptions, authDataKeys: IAuthDataSanitizeKeys) {
|
||||
export const REDACTED = '**hidden**';
|
||||
|
||||
function isObject(obj: unknown): obj is IDataObject {
|
||||
return isPlainObject(obj);
|
||||
}
|
||||
|
||||
function redact<T = unknown>(obj: T, secrets: string[]): T {
|
||||
if (typeof obj === 'string') {
|
||||
return secrets.reduce((safe, secret) => safe.replace(secret, REDACTED), obj) as T;
|
||||
}
|
||||
|
||||
if (Array.isArray(obj)) {
|
||||
return obj.map((item) => redact(item, secrets)) as T;
|
||||
} else if (isObject(obj)) {
|
||||
for (const [key, value] of Object.entries(obj)) {
|
||||
(obj as IDataObject)[key] = redact(value, secrets);
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
export function sanitizeUiMessage(
|
||||
request: IRequestOptions,
|
||||
authDataKeys: IAuthDataSanitizeKeys,
|
||||
secrets?: string[],
|
||||
) {
|
||||
let sendRequest = request as unknown as IDataObject;
|
||||
|
||||
// Protect browser from sending large binary data
|
||||
@@ -38,7 +68,7 @@ export function sanitizeUiMessage(request: IRequestOptions, authDataKeys: IAuthD
|
||||
...request,
|
||||
body: `Binary data got replaced with this text. Original was a Buffer with a size of ${
|
||||
(request.body as string).length
|
||||
} byte.`,
|
||||
} bytes.`,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -50,7 +80,7 @@ export function sanitizeUiMessage(request: IRequestOptions, authDataKeys: IAuthD
|
||||
// eslint-disable-next-line @typescript-eslint/no-loop-func
|
||||
(acc: IDataObject, curr) => {
|
||||
acc[curr] = authDataKeys[requestProperty].includes(curr)
|
||||
? '** hidden **'
|
||||
? REDACTED
|
||||
: (sendRequest[requestProperty] as IDataObject)[curr];
|
||||
return acc;
|
||||
},
|
||||
@@ -59,9 +89,33 @@ export function sanitizeUiMessage(request: IRequestOptions, authDataKeys: IAuthD
|
||||
};
|
||||
}
|
||||
|
||||
if (secrets && secrets.length > 0) {
|
||||
return redact(sendRequest, secrets);
|
||||
}
|
||||
|
||||
return sendRequest;
|
||||
}
|
||||
|
||||
export function getSecrets(
|
||||
properties: INodeProperties[],
|
||||
credentials: ICredentialDataDecryptedObject,
|
||||
): string[] {
|
||||
const sensitivePropNames = new Set(
|
||||
properties.filter((prop) => prop.typeOptions?.password).map((prop) => prop.name),
|
||||
);
|
||||
|
||||
const secrets = Object.entries(credentials)
|
||||
.filter(([propName]) => sensitivePropNames.has(propName))
|
||||
.map(([_, value]) => value)
|
||||
.filter((value): value is string => typeof value === 'string');
|
||||
const oauthAccessToken = get(credentials, 'oauthTokenData.access_token');
|
||||
if (typeof oauthAccessToken === 'string') {
|
||||
secrets.push(oauthAccessToken);
|
||||
}
|
||||
|
||||
return secrets;
|
||||
}
|
||||
|
||||
export const getOAuth2AdditionalParameters = (nodeCredentialType: string) => {
|
||||
const oAuth2Options: { [credentialType: string]: IOAuth2Options } = {
|
||||
bitlyOAuth2Api: {
|
||||
|
||||
Reference in New Issue
Block a user