CodeQL 文档

路径表达式中使用不受控制的数据

ID: js/path-injection
Kind: path-problem
Security severity: 7.5
Severity: error
Precision: high
Tags:
   - security
   - external/cwe/cwe-022
   - external/cwe/cwe-023
   - external/cwe/cwe-036
   - external/cwe/cwe-073
   - external/cwe/cwe-099
Query suites:
   - javascript-code-scanning.qls
   - javascript-security-extended.qls
   - javascript-security-and-quality.qls

点击查看 CodeQL 仓库中的查询

使用从用户控制的数据构建的路径访问文件,可能允许攻击者访问意外资源。这会导致敏感信息被泄露或删除,或攻击者能够通过修改意外文件来影响行为。

建议

在使用用户输入构建文件路径之前对其进行验证。

您应该使用的验证方法取决于您是否要允许用户指定可能跨越多个文件夹的具有多个组件的复杂路径,还是只允许没有路径组件的简单文件名。

在前一种情况下,常见的策略是确保构建的文件路径包含在一个安全的根文件夹中。首先,使用 path.resolvefs.realpathSync 规范化路径,以删除任何“..” 段。您应该始终规范化文件路径,因为以根文件夹开头的未规范化路径仍然可用于访问根文件夹之外的文件。然后,在规范化路径之后,检查路径是否以根文件夹开头。

在后一种情况下,您可以使用像 sanitize-filename npm 包这样的库来消除文件路径中的任何特殊字符。请注意,仅删除“../”序列是不够的:例如,将此过滤器应用于“…/…//”仍将导致字符串“../”。

最后,最简单(但最严格)的选择是使用安全模式的允许列表,并确保用户输入与其中一个模式匹配。

示例

在第一个(不好的)示例中,代码从 HTTP 请求中读取文件名,然后在根文件夹中访问该文件。恶意用户可以输入包含“../”段的文件名,以导航到根文件夹之外并访问敏感文件。

const fs = require('fs'),
      http = require('http'),
      url = require('url');

const ROOT = "/var/www/";

var server = http.createServer(function(req, res) {
  let filePath = url.parse(req.url, true).query.path;

  // BAD: This function uses unsanitized input that can read any file on the file system.
  res.write(fs.readFileSync(ROOT + filePath, 'utf8'));
});

第二个(好的)示例展示了如何通过清理文件路径来避免访问敏感文件。首先,代码解析相对于根文件夹的文件名,在此过程中规范化路径并删除任何“../”段。然后,代码调用 fs.realpathSync 来解析路径中的任何符号链接。最后,代码检查规范化的路径是否以根文件夹的路径开头,确保文件包含在根文件夹内。

const fs = require('fs'),
      http = require('http'),
      path = require('path'),
      url = require('url');

const ROOT = "/var/www/";

var server = http.createServer(function(req, res) {
  let filePath = url.parse(req.url, true).query.path;

  // GOOD: Verify that the file path is under the root directory
  filePath = fs.realpathSync(path.resolve(ROOT, filePath));
  if (!filePath.startsWith(ROOT)) {
    res.statusCode = 403;
    res.end();
    return;
  }
  res.write(fs.readFileSync(filePath, 'utf8'));
});

参考资料

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