From 4b4d4c05431077b9c015aa6341c4d03f5eee4d81 Mon Sep 17 00:00:00 2001 From: beejak Date: Mon, 20 Apr 2026 09:56:31 +0530 Subject: [PATCH] fix: stop executing user code in SSO expression validator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit validateExpression() was calling new Function() to validate SSO claim mapping expressions, then immediately invoking the returned function with mock arguments. Executing user-provided code in the browser gives it access to window, document, fetch, and the full browser environment. The Function constructor alone throws SyntaxError for invalid JS — we never needed to call the function to validate syntax. Remove the fn() call and the now-unused mockClaims Proxy. Some code in this commit was written with assistance from Claude Sonnet 4.6 (AI). --- .../components/RuleMappingExpressionInput.vue | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/packages/frontend/editor-ui/src/features/settings/sso/provisioning/components/RuleMappingExpressionInput.vue b/packages/frontend/editor-ui/src/features/settings/sso/provisioning/components/RuleMappingExpressionInput.vue index eea13c230c8..82492190052 100644 --- a/packages/frontend/editor-ui/src/features/settings/sso/provisioning/components/RuleMappingExpressionInput.vue +++ b/packages/frontend/editor-ui/src/features/settings/sso/provisioning/components/RuleMappingExpressionInput.vue @@ -51,21 +51,18 @@ const dialogVisible = ref(false); let editorView: EditorView | null = null; let expandedEditorView: EditorView | null = null; -// Mock $claims: every property returns a real array so .includes() works but .includ() throws -const mockClaims = new Proxy( - {}, - { get: (_target, prop) => (typeof prop === 'symbol' ? undefined : ['mock']) }, -); - function validateExpression(value: string): boolean { if (!value.trim()) return true; const match = value.match(/^\{\{(.+)\}\}$/s); const jsContent = match ? match[1].trim() : value.trim(); if (!jsContent) return true; try { + // Syntax-only validation: the Function constructor throws SyntaxError for + // invalid JS without executing the body. Do NOT call the returned function — + // calling it would execute user-provided code in the browser context where + // window, document, and fetch are all reachable. // eslint-disable-next-line no-new-func, @typescript-eslint/no-implied-eval - const fn = new Function('$claims', '$oidc', '$saml', '$provider', `return (${jsContent})`); - fn(mockClaims, { idToken: {}, userInfo: {} }, { attributes: {} }, 'oidc'); + new Function('$claims', '$oidc', '$saml', '$provider', `return (${jsContent})`); return true; } catch { return false;