修复Checkmarx检测到的Prototype Pollution原型污染错误
修复Checkmarx检测的原型污染问题
你的代码已经做了白名单校验,但Checkmarx仍告警原型污染,核心原因是你用普通对象{}存储查询参数,它继承了Object原型链,理论上存在被恶意参数污染原型的风险(即便当前白名单已拦截)。以下是针对性修复方案:
关键修复点
- 使用
Object.create(null)替代{}创建查询参数对象,该对象无任何原型链,彻底杜绝原型污染可能 - 新增特殊属性过滤逻辑,提前拦截
__proto__、constructor、prototype这类高危键名,进一步加固安全 - 优化参数值处理,避免空值传入
decodeURIComponent导致报错
修改后的完整代码
var QueryString = (function () { // 创建无原型的对象,彻底切断原型链,避免原型污染 var query_string = Object.create(null); const allowed = new Set([ 'rqid', 'rowId', 'sid', 'RequestId', 'RequestTypeID', 'mode', 'id', 'requestIdList', ]); // 匹配高危原型相关键名的正则 const forbiddenKeyPattern = /^(__proto__|constructor|prototype)$/; var rawQuery = window.location.search.substring(1); // DOMPurify用于XSS防护,若仅处理查询参数可保留,不影响原型污染修复 var sanitizedQuery = DOMPurify.sanitize(rawQuery); var paramPairs = sanitizedQuery.split("&"); for (var i = 0; i < paramPairs.length; i++) { var pair = paramPairs[i].split("="); var key = pair[0]?.trim(); // 跳过空键、空白键或高危键 if (!key || forbiddenKeyPattern.test(key)) { continue; } // 处理空参数值,避免decodeURIComponent报错 var value = pair[1] ? decodeURIComponent(pair[1].trim()) : ''; // 仅处理白名单内的参数 if (!allowed.has(key)) { continue; } // 处理多值参数的逻辑 if (typeof query_string[key] === "undefined") { query_string[key] = value; } else if (typeof query_string[key] === "string") { query_string[key] = [query_string[key], value]; } else { query_string[key].push(value); } } return query_string; })();
修复细节说明
- 无原型对象:
Object.create(null)创建的对象不具备__proto__属性,也不会继承Object的任何原型方法,从根源上消除了原型属性被篡改的可能,这是修复原型污染最彻底的方式 - 高危键拦截:通过正则提前过滤掉与原型相关的特殊键名,即使白名单出现疏漏,也能直接阻断恶意参数进入后续赋值逻辑
- 鲁棒性优化:增加了键和值的空白处理,以及空值判断,避免因不规范的查询参数导致运行时错误
内容的提问来源于stack exchange,提问作者h.z.
相关产品推荐
相关产品推荐

