From 4067378b572cbe962a729346e3505479105a1c0c Mon Sep 17 00:00:00 2001 From: Valentin Serra Date: Wed, 27 Mar 2024 12:10:43 +0100 Subject: [PATCH] fix: prevent prototype polution through keys and paths Closes #1111 --- .../src/features/properties-panel/Util.js | 13 +++++++++++++ .../features/properties-panel/entries/KeyEntry.js | 6 +++++- .../features/properties-panel/entries/PathEntry.js | 10 +++++++--- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/packages/form-js-editor/src/features/properties-panel/Util.js b/packages/form-js-editor/src/features/properties-panel/Util.js index 9e05429a2..6adc5cb58 100644 --- a/packages/form-js-editor/src/features/properties-panel/Util.js +++ b/packages/form-js-editor/src/features/properties-panel/Util.js @@ -68,6 +68,19 @@ export function isValidDotPath(path) { return /^\w+(\.\w+)*$/.test(path); } +/** + * @param {string} path + */ +export function isProhibitedPath(path) { + const prohibitedSegments = [ + '__proto__', + 'prototype', + 'constructor' + ]; + + return path.split('.').some(segment => prohibitedSegments.includes(segment)); +} + export const LABELED_NON_INPUTS = [ 'button', 'group', diff --git a/packages/form-js-editor/src/features/properties-panel/entries/KeyEntry.js b/packages/form-js-editor/src/features/properties-panel/entries/KeyEntry.js index 27c5adcd4..b91604052 100644 --- a/packages/form-js-editor/src/features/properties-panel/entries/KeyEntry.js +++ b/packages/form-js-editor/src/features/properties-panel/entries/KeyEntry.js @@ -1,6 +1,6 @@ import { isString, get } from 'min-dash'; -import { hasIntegerPathSegment, isValidDotPath } from '../Util'; +import { hasIntegerPathSegment, isProhibitedPath, isValidDotPath } from '../Util'; import { useService } from '../hooks'; @@ -76,6 +76,10 @@ function Key(props) { return 'Must not contain numerical path segments.'; } + if (isProhibitedPath(value)) { + return 'Must not be a prohibited path.'; + } + const replacements = { [ field.id ]: value.split('.') }; diff --git a/packages/form-js-editor/src/features/properties-panel/entries/PathEntry.js b/packages/form-js-editor/src/features/properties-panel/entries/PathEntry.js index 7eb9d5544..c833b1475 100644 --- a/packages/form-js-editor/src/features/properties-panel/entries/PathEntry.js +++ b/packages/form-js-editor/src/features/properties-panel/entries/PathEntry.js @@ -4,7 +4,7 @@ import { useService } from '../hooks'; import { TextFieldEntry, isTextFieldEntryEdited } from '@bpmn-io/properties-panel'; -import { isValidDotPath } from '../Util'; +import { isProhibitedPath, isValidDotPath, hasIntegerPathSegment } from '../Util'; import { useCallback } from 'preact/hooks'; @@ -80,11 +80,15 @@ function Path(props) { } // Check for integer segments in the path - const hasIntegerPathSegment = value.split('.').some(segment => /^\d+$/.test(segment)); - if (hasIntegerPathSegment) { + if (hasIntegerPathSegment(value)) { return 'Must not contain numerical path segments.'; } + // Check for special prohibited paths + if (isProhibitedPath(value)) { + return 'Must not be a prohibited path.'; + } + // Check for path collisions const options = { replacements: {