CodeQL 文档

深度对象遍历导致资源耗尽

ID: js/resource-exhaustion-from-deep-object-traversal
Kind: path-problem
Security severity: 7.5
Severity: warning
Precision: high
Tags:
   - security
   - external/cwe/cwe-400
Query suites:
   - javascript-code-scanning.qls
   - javascript-security-extended.qls
   - javascript-security-and-quality.qls

点击查看 CodeQL 代码库中的查询

使用分配大量内存的方法处理用户控制的数据会导致拒绝服务攻击。

如果 JSON 模式验证库ajv配置为allErrors: true,则分配的错误对象数量没有限制。攻击者可以利用这一点,发送一个故意包含大量错误的对象,在某些情况下,还会包含越来越长的错误消息。这会导致服务由于缓慢的错误检查过程而变得无响应。

建议

不要在生产环境中使用allErrors: true

示例

在下面的示例中,用户提交的对象req.body使用ajvallErrors: true进行验证。

import express from 'express';
import Ajv from 'ajv';

let ajv = new Ajv({ allErrors: true });
ajv.addSchema(require('./input-schema'), 'input');

var app = express();
app.get('/user/:id', function(req, res) {
	if (!ajv.validate('input', req.body)) {
		res.end(ajv.errorsText());
		return;
	}
	// ...
});

虽然这确保了req.body符合模式,但验证本身可能容易受到拒绝服务攻击。攻击者可以发送一个包含大量错误的对象,导致服务器内存不足。

解决方案是不传递allErrors: true,这意味着ajv只会报告第一个错误,而不是所有错误。

import express from 'express';
import Ajv from 'ajv';

let ajv = new Ajv({ allErrors: process.env['REST_DEBUG'] });
ajv.addSchema(require('./input-schema'), 'input');

var app = express();
app.get('/user/:id', function(req, res) {
	if (!ajv.validate('input', req.body)) {
		res.end(ajv.errorsText());
		return;
	}
	// ...
});

参考资料

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