CodeQL 文档

缺少正则表达式锚点

ID: js/regex/missing-regexp-anchor
Kind: problem
Security severity: 7.8
Severity: warning
Precision: medium
Tags:
   - correctness
   - security
   - external/cwe/cwe-020
Query suites:
   - javascript-security-extended.qls
   - javascript-security-and-quality.qls

点击查看 CodeQL 仓库中的查询

使用正则表达式清理不受信任的输入是一种常见的技术。但是,在没有锚点(例如 ^$)的情况下,使用正则表达式匹配不受信任的输入很容易出错。恶意输入可以通过在意外位置嵌入允许的模式之一来绕过此类安全检查。

即使匹配不在安全关键的上下文中进行,当正则表达式意外匹配时,它也可能导致不良行为。

建议

使用锚点确保正则表达式在预期位置匹配。

示例

以下示例代码检查 URL 重定向是否会到达 example.com 域或其子域之一,而不是某个恶意站点。

app.get("/some/path", function(req, res) {
    let url = req.param("url");
    // BAD: the host of `url` may be controlled by an attacker
    if (url.match(/https?:\/\/www\.example\.com\//)) {
        res.redirect(url);
    }
});

但是,使用正则表达式匹配的检查很容易绕过。例如,通过在查询字符串组件中嵌入 http://example.com/http://evil-example.net/?x=http://example.com/。通过在正则表达式中使用锚点来解决这些缺点。

app.get("/some/path", function(req, res) {
    let url = req.param("url");
    // GOOD: the host of `url` can not be controlled by an attacker
    if (url.match(/^https?:\/\/www\.example\.com\//)) {
        res.redirect(url);
    }
});

另一个相关的错误是在正则表达式中写多个备选方案,但只为其中一个备选方案包含锚点。例如,正则表达式 /^www\.example\.com|beta\.example\.com/ 将匹配主机 evil.beta.example.com,因为正则表达式被解析为 /(^www\.example\.com)|(beta\.example\.com)/

参考资料

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