CodeQL 文档

缺少正则表达式锚点

ID: swift/missing-regexp-anchor
Kind: problem
Security severity: 7.8
Severity: warning
Precision: high
Tags:
   - correctness
   - security
   - external/cwe/cwe-020
Query suites:
   - swift-code-scanning.qls
   - swift-security-extended.qls
   - swift-security-and-quality.qls

点击查看 CodeQL 仓库中的查询

使用正则表达式对不受信任的输入进行清理是一种常见的技术,但恶意攻击者可能会将允许的模式之一嵌入到意想不到的位置。为了防止这种情况,您应该在正则表达式中使用锚点,例如 ^$

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

建议

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

示例

以下示例代码试图检查 URL 重定向是否将到达 example.com 域,而不是恶意网站

func handleUrl(_ urlString: String) {
    // get the 'url=' parameter from the URL
    let components = URLComponents(string: urlString)
    let redirectParam = components?.queryItems?.first(where: { $0.name == "url" })

    // check we trust the host
    let regex = try Regex(#"https?://www\.example\.com"#) // BAD: the host of `url` may be controlled by an attacker
    if let match = redirectParam?.value?.firstMatch(of: regex) {
        // ... trust the URL ...
    }
}

但是,此正则表达式检查很容易绕过,恶意攻击者可以在恶意网站的查询字符串组件中嵌入 http://www.example.com/。例如,http://evil-example.net/?x=http://www.example.com/。相反,您应该在正则表达式检查中使用锚点

func handleUrl(_ urlString: String) {
    // get the 'url=' parameter from the URL
    let components = URLComponents(string: urlString)
    let redirectParam = components?.queryItems?.first(where: { $0.name == "url" })

    // check we trust the host
    let regex = try Regex(#"^https?://www\.example\.com"#) // GOOD: the host of `url` can not be controlled by an attacker
    if let match = redirectParam?.value?.firstMatch(of: regex) {
        // ... trust the URL ...
    }
}

如果您需要编写正则表达式来匹配多个主机,则应为所有备选方案包含一个锚点。例如,正则表达式 /^www\.example\.com|beta\.example\.com/ 将匹配主机 evil.beta.example.com,因为正则表达式被解析为 /(^www\.example\.com)|(beta\.example\.com)/

参考资料

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