缺少正则表达式锚点¶
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
使用正则表达式对不受信任的输入进行清理是一种常见的技术,但恶意攻击者可能会将允许的模式之一嵌入到意想不到的位置。为了防止这种情况,您应该在正则表达式中使用锚点,例如 ^
或 $
。
即使匹配不在安全敏感的上下文中进行,当正则表达式意外匹配时,它仍然可能导致不良行为。
建议¶
使用锚点确保正则表达式在预期位置匹配。
示例¶
以下示例代码试图检查 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)/
。
参考资料¶
OWASP:SSRF
OWASP:XSS 未验证重定向和转发备忘单.
常见弱点枚举:CWE-20.