CodeQL 文档

资源耗尽

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

单击以在 CodeQL 仓库中查看查询

应用程序受其可以利用的资源数量的限制。不尊重这些限制可能会导致应用程序无响应或崩溃。因此,如果攻击者可以控制分配对象的尺寸或生命周期,则这是一个问题。

建议

确保攻击者无法控制对象的尺寸及其生命周期。如果对象的尺寸和生命周期必须由外部方控制,请确保限制对象的尺寸和生命周期,以确保它们在可接受的范围内。

示例

以下示例分配了一个尺寸由用户控制的缓冲区。

var http = require("http"),
    url = require("url");

var server = http.createServer(function(req, res) {
	var size = parseInt(url.parse(req.url, true).query.size);

	let buffer = Buffer.alloc(size); // BAD

	// ... use the buffer
});

这存在问题,因为攻击者可以选择一个尺寸,使应用程序耗尽内存。更糟糕的是,在旧版本的 Node.js 中,这可能会泄露机密内存。为了防止此类攻击,请限制缓冲区尺寸

var http = require("http"),
    url = require("url");

var server = http.createServer(function(req, res) {
	var size = parseInt(url.parse(req.url, true).query.size);

	if (size > 1024) {
		res.statusCode = 400;
		res.end("Bad request.");
		return;
	}

	let buffer = Buffer.alloc(size); // GOOD

	// ... use the buffer
});

示例

作为另一个示例,请考虑一个应用程序,该应用程序分配一个尺寸由用户控制的数组,然后用值填充它

var http = require("http"),
    url = require("url");

var server = http.createServer(function(req, res) {
	var size = parseInt(url.parse(req.url, true).query.size);

	let dogs = new Array(size).fill("dog"); // BAD

	// ... use the dog
});

数组本身的分配没有问题,因为数组是稀疏分配的,但随后填充数组将需要很长时间,导致应用程序无响应,甚至耗尽内存。同样,对尺寸的限制将阻止攻击

var http = require("http"),
    url = require("url");

var server = http.createServer(function(req, res) {
	var size = parseInt(url.parse(req.url, true).query.size);

	if (size > 1024) {
		res.statusCode = 400;
		res.end("Bad request.");
		return;
	}

	let dogs = new Array(size).fill("dog"); // GOOD

	// ... use the dogs
});

示例

最后,以下示例允许用户选择执行函数后的延迟时间

var http = require("http"),
    url = require("url");

var server = http.createServer(function(req, res) {
	var delay = parseInt(url.parse(req.url, true).query.delay);

	setTimeout(f, delay); // BAD

});

这存在问题,因为长时间延迟实际上会使应用程序无限期地等待,然后再执行函数。因此,反复注册此类延迟将耗尽应用程序中的所有内存。对延迟的限制将阻止攻击

var http = require("http"),
    url = require("url");

var server = http.createServer(function(req, res) {
	var delay = parseInt(url.parse(req.url, true).query.delay);

	if (delay > 1000) {
		res.statusCode = 400;
		res.end("Bad request.");
		return;
	}

	setTimeout(f, delay); // GOOD

});

参考

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