由于您在 ? 分隔符之后将 params_str_submitted_by_user 附加到基本 URL,因此您可以安全地免受这种将域上下文更改为用户名或密码的攻击:
假设 URL 是 http://example.com 和 params_str_submitted_by_user 是 @evil.com,而您的 URL 字符串连接中没有 / 或 ? 字符。
这将使您的 URL http://example.com@evil.com 这实际上意味着用户名 example.com 在域 evil.com。
但是,the username cannot contain the ? (nor slash) character,所以你应该是安全的,因为你强制连接用户名。在您的情况下,网址变为:
http://example.com?@evil.com
或
http://example.com/?@evil.com
如果您在基本 URL 中包含斜杠(更好的做法)。这些是安全的,因为它所做的只是将您的网站 evil.com 作为查询字符串值传递,因为 @evil.com 将不再被解析器解释为域。
如果连换行符都留在里面,而用户可以任意操作 HTTP 标头,最坏的情况是什么?
这取决于您的 http_get 函数在清理值方面的能力。如果http_get 没有在内部去除换行符,那么攻击者就有可能控制从您的应用程序发送的标头。
例如如果http_get 内部创建了以下请求
GET <url> HTTP/1.1
Host: <url.domain>
所以在合法使用下,它的工作方式如下:
http_get("https://example.com/foo/bar")
生成
GET /foo/bar HTTP/1.1
Host: example.com
攻击者可以将params_str_submitted_by_user 设置为
<space>HTTP/1.1\r\nHost: example.org\r\nCookie: foo=bar\r\n\r\n
这会导致您的代码调用
http_get("https://example.com/" + "?" + "<space>HTTP/1.1\r\nHost: example.org\r\nCookie: foo=bar\r\n\r\n")
这会导致请求被
GET / HTTP/1.1
Host: example.org
Cookie: foo=bar
HTTP/1.1
Host: example.com
根据http_get 解析域的方式,这可能不会导致请求转到example.org 而不是example.com - 它只是在操作标头(除非example.org 是同一站点上的另一个站点 IP 地址 作为您的站点)。但是,攻击者已经设法操纵标头并添加自己的 cookie 值。攻击者的优势取决于他们在您的特定设置下可以从他们那里获得什么 - 不一定有任何普遍优势,如果他们可以通过以下方式欺骗您的代码以意想不到的方式表现,那将更像是一个逻辑漏洞利用使其在攻击者的控制下发出请求。
你应该怎么做?
为了防止意外和未知,请使用正确处理标头注入的http_get 版本。许多现代语言现在在内部处理这种情况。
或者 - 如果 http_get 是您自己的实现,请确保它清理或拒绝包含无效字符的 URL,例如回车或换行以及 URL 中无效的其他参数。 See this question for list of valid characters.