主机名不完整的正则表达式¶
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
清理不受信任的 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 ...
}
}
参考资料¶
OWASP: 服务器端请求伪造.
OWASP: 未经验证的重定向和转发备忘单.
常见弱点枚举: CWE-20.