CodeQL 文档

循环边界注入

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

单击查看 CodeQL 仓库中的查询

使用不受信任对象的 .length 属性作为循环边界可能会导致无限循环,因为恶意攻击者可以将 .length 属性设置为一个非常大的数字。例如,当一个期望数组的程序传递一个类似于 {length: 1e100} 的 JSON 对象时,循环将运行 10100 次。这可能会导致程序挂起或耗尽内存,可用于发动拒绝服务 (DoS) 攻击。

建议

检查该对象是否确实是一个数组,或者限制 .length 属性的大小。

示例

在下面的示例中,一个 HTTP 请求处理程序使用用户控制的对象 objobj.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]);
    }
});

参考

  • ©GitHub, Inc.
  • 条款
  • 隐私