循环边界注入¶
ID: js/loop-bound-injection
Kind: path-problem
Security severity: 7.5
Severity: warning
Precision: high
Tags:
- security
- external/cwe/cwe-834
- external/cwe/cwe-730
Query suites:
- javascript-code-scanning.qls
- javascript-security-extended.qls
- javascript-security-and-quality.qls
使用不受信任对象的 .length
属性作为循环边界可能会导致无限循环,因为恶意攻击者可以将 .length
属性设置为一个非常大的数字。例如,当一个期望数组的程序传递一个类似于 {length: 1e100}
的 JSON 对象时,循环将运行 10100 次。这可能会导致程序挂起或耗尽内存,可用于发动拒绝服务 (DoS) 攻击。
建议¶
检查该对象是否确实是一个数组,或者限制 .length
属性的大小。
示例¶
在下面的示例中,一个 HTTP 请求处理程序使用用户控制的对象 obj
的 obj.length
属性来迭代该对象,并将元素从 obj
复制到一个数组中。
var express = require('express');
var app = express();
app.post("/foo", (req, res) => {
var obj = req.body;
var ret = [];
// Potential DoS if obj.length is large.
for (var i = 0; i < obj.length; i++) {
ret.push(obj[i]);
}
});
这并不安全,因为攻击者可以控制 obj.length
的值,从而导致循环无限迭代。这里通过强制用户控制的对象为数组来修复潜在的 DoS。
var express = require('express');
var app = express();
app.post("/foo", (req, res) => {
var obj = req.body;
if (!(obj instanceof Array)) { // Prevents DoS.
return [];
}
var ret = [];
for (var i = 0; i < obj.length; i++) {
ret.push(obj[i]);
}
});