CodeQL 文档

主机名不完整的正则表达式

ID: swift/incomplete-hostname-regexp
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 是防止诸如请求伪造和恶意重定向等攻击的重要技术。通常,这是通过检查 URL 的主机是否在允许的主机集中来完成的。

如果正则表达式执行了此类检查,则很容易通过不适当地转义 . 元字符而意外地使检查过于宽松。即使检查未用于安全敏感的上下文中,不完整的检查在意外成功时仍可能导致不良行为。

建议

在构建用于安全检查的正则表达式时,请适当地转义所有元字符,并特别注意 . 元字符。

示例

以下示例代码检查 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 = #/^(www|beta).example.com//#  // BAD
    if let match = redirectParam?.value?.firstMatch(of: regex) {
        // ... trust the URL ...
    }
}

但是,此检查很容易绕过,因为未转义的 . 允许 example.com 之前的任何字符,从而有效地允许重定向到攻击者控制的域,例如 wwwXexample.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 = #/^(www|beta)\.example\.com//#  // GOOD
    if let match = redirectParam?.value?.firstMatch(of: regex) {
        // ... trust the URL ...
    }
}

参考资料

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