mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-25 04:34:06 -08:00
fix(editor): Fixing XSS vulnerability in toast messages (#10329)
Co-authored-by: Adi <aditya@netroy.in>
This commit is contained in:
parent
b6c47c0e32
commit
38bdd9f5d0
|
@ -94,6 +94,7 @@ async function send() {
|
||||||
message: Number(form.value.value) >= 8 ? i18n.baseText('prompts.npsSurvey.reviewUs') : '',
|
message: Number(form.value.value) >= 8 ? i18n.baseText('prompts.npsSurvey.reviewUs') : '',
|
||||||
type: 'success',
|
type: 'success',
|
||||||
duration: 15000,
|
duration: 15000,
|
||||||
|
dangerouslyUseHTMLString: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|
|
@ -16,6 +16,7 @@ import { useUIStore } from '@/stores/ui.store';
|
||||||
import { useTelemetry } from './useTelemetry';
|
import { useTelemetry } from './useTelemetry';
|
||||||
import { useRootStore } from '@/stores/root.store';
|
import { useRootStore } from '@/stores/root.store';
|
||||||
import { isFullExecutionResponse } from '@/utils/typeGuards';
|
import { isFullExecutionResponse } from '@/utils/typeGuards';
|
||||||
|
import { sanitizeHtml } from '@/utils/htmlUtils';
|
||||||
|
|
||||||
export const useExecutionDebugging = () => {
|
export const useExecutionDebugging = () => {
|
||||||
const telemetry = useTelemetry();
|
const telemetry = useTelemetry();
|
||||||
|
@ -61,7 +62,7 @@ export const useExecutionDebugging = () => {
|
||||||
h(
|
h(
|
||||||
'ul',
|
'ul',
|
||||||
{ class: 'mt-l ml-l' },
|
{ class: 'mt-l ml-l' },
|
||||||
matchingPinnedNodeNames.map((name) => h('li', name)),
|
matchingPinnedNodeNames.map((name) => h('li', sanitizeHtml(name))),
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
|
@ -328,6 +328,7 @@ export function usePushConnection({ router }: { router: ReturnType<typeof useRou
|
||||||
message: `${action} <a href="https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.wait/" target="_blank">More info</a>`,
|
message: `${action} <a href="https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.wait/" target="_blank">More info</a>`,
|
||||||
type: 'success',
|
type: 'success',
|
||||||
duration: 0,
|
duration: 0,
|
||||||
|
dangerouslyUseHTMLString: true,
|
||||||
});
|
});
|
||||||
} else if (runDataExecuted.finished !== true) {
|
} else if (runDataExecuted.finished !== true) {
|
||||||
titleChange.titleSet(workflow.name as string, 'ERROR');
|
titleChange.titleSet(workflow.name as string, 'ERROR');
|
||||||
|
@ -438,7 +439,6 @@ export function usePushConnection({ router }: { router: ReturnType<typeof useRou
|
||||||
message: runDataExecutedErrorMessage,
|
message: runDataExecutedErrorMessage,
|
||||||
type: 'error',
|
type: 'error',
|
||||||
duration: 0,
|
duration: 0,
|
||||||
dangerouslyUseHTMLString: true,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ export interface NotificationErrorWithNodeAndDescription extends ApplicationErro
|
||||||
}
|
}
|
||||||
|
|
||||||
const messageDefaults: Partial<Omit<NotificationOptions, 'message'>> = {
|
const messageDefaults: Partial<Omit<NotificationOptions, 'message'>> = {
|
||||||
dangerouslyUseHTMLString: true,
|
dangerouslyUseHTMLString: false,
|
||||||
position: 'bottom-right',
|
position: 'bottom-right',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -32,28 +32,28 @@ export function useToast() {
|
||||||
const i18n = useI18n();
|
const i18n = useI18n();
|
||||||
|
|
||||||
function showMessage(messageData: Partial<NotificationOptions>, track = true) {
|
function showMessage(messageData: Partial<NotificationOptions>, track = true) {
|
||||||
messageData = { ...messageDefaults, ...messageData };
|
const { message, title } = messageData;
|
||||||
|
const params = { ...messageDefaults, ...messageData };
|
||||||
|
|
||||||
Object.defineProperty(messageData, 'message', {
|
if (typeof message === 'string') {
|
||||||
value:
|
params.message = sanitizeHtml(message);
|
||||||
typeof messageData.message === 'string'
|
}
|
||||||
? sanitizeHtml(messageData.message)
|
|
||||||
: messageData.message,
|
|
||||||
writable: true,
|
|
||||||
enumerable: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const notification = Notification(messageData);
|
if (typeof title === 'string') {
|
||||||
|
params.title = sanitizeHtml(title);
|
||||||
|
}
|
||||||
|
|
||||||
if (messageData.duration === 0) {
|
const notification = Notification(params);
|
||||||
|
|
||||||
|
if (params.duration === 0) {
|
||||||
stickyNotificationQueue.push(notification);
|
stickyNotificationQueue.push(notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (messageData.type === 'error' && track) {
|
if (params.type === 'error' && track) {
|
||||||
telemetry.track('Instance FE emitted error', {
|
telemetry.track('Instance FE emitted error', {
|
||||||
error_title: messageData.title,
|
error_title: params.title,
|
||||||
error_message: messageData.message,
|
error_message: params.message,
|
||||||
caused_by_credential: causedByCredential(messageData.message as string),
|
caused_by_credential: causedByCredential(params.message as string),
|
||||||
workflow_id: workflowsStore.workflowId,
|
workflow_id: workflowsStore.workflowId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -133,6 +133,7 @@ export function useToast() {
|
||||||
${collapsableDetails(error)}`,
|
${collapsableDetails(error)}`,
|
||||||
type: 'error',
|
type: 'error',
|
||||||
duration: 0,
|
duration: 0,
|
||||||
|
dangerouslyUseHTMLString: true,
|
||||||
},
|
},
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
|
|
@ -18,6 +18,10 @@ export function sanitizeHtml(dirtyHtml: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ALLOWED_HTML_ATTRIBUTES.includes(name) || name.startsWith('data-')) {
|
if (ALLOWED_HTML_ATTRIBUTES.includes(name) || name.startsWith('data-')) {
|
||||||
|
// href is allowed but we need to sanitize certain protocols
|
||||||
|
if (name === 'href' && !value.match(/^https?:\/\//gm)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
return `${name}="${friendlyAttrValue(value)}"`;
|
return `${name}="${friendlyAttrValue(value)}"`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue