From 935393698092fc99d42c4e753cd97a6789d9225b Mon Sep 17 00:00:00 2001 From: Codex Security Bot Date: Sun, 8 Mar 2026 07:59:47 +0000 Subject: [PATCH] security: harden highlight directive against html injection --- cmdb-ui/src/directive/highlight/highlight.js | 36 +++++++++++++++----- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/cmdb-ui/src/directive/highlight/highlight.js b/cmdb-ui/src/directive/highlight/highlight.js index d76688a3..e0c017ee 100644 --- a/cmdb-ui/src/directive/highlight/highlight.js +++ b/cmdb-ui/src/directive/highlight/highlight.js @@ -1,14 +1,34 @@ import './highlight.less' +const escapeRegExp = (value) => { + return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') +} + +const escapeHtml = (value) => { + return value + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, ''') +} + +const sanitizeClassName = (value) => { + const className = value ? `${value}` : 'ops-text-highlight' + return /^[A-Za-z0-9_-]+$/.test(className) ? className : 'ops-text-highlight' +} + const highlight = (el, binding) => { - if (binding.value.value) { - let testValue = `${binding.value.value}` - if (['(', ')', '$'].includes(testValue)) { - testValue = `\\${testValue}` - } - const regex = new RegExp(`(${testValue})`, 'gi') - el.innerHTML = el.innerText.replace(regex, `$1`) - } + const options = (binding && binding.value) || {} + if (options.value === undefined || options.value === null || `${options.value}` === '') { + return + } + + const text = escapeHtml(el.innerText || '') + const keyword = escapeRegExp(`${options.value}`) + const className = sanitizeClassName(options.class) + const regex = new RegExp(`(${keyword})`, 'gi') + el.innerHTML = text.replace(regex, `$1`) } export default highlight