目前,我的软件具有以下工作流程
为了实现步骤2,用户必须将他用于搜索的URL参数作为字符串发送(例如age=10&gender=M
)。
然后服务器将http_get(url + "?" + params_str_submitted_by_user)
恶意用户是否可以通过操纵params_str_submitted_by_user
使服务器连接到非预期的服务器?
如果留下新行并且用户可以随意操纵HTTP标头,最糟糕的情况是什么?
答案 0 :(得分:3)
当您在params_str_submitted_by_user
分隔符之后将?
附加到基本URL时,您可以避免在域的上下文更改为用户名或密码时使用的此类攻击:
假设网址为http://example.com
且params_str_submitted_by_user
为@evil.com
,并且您的网址字符串连接中没有/
或?
个字符。
这会使您的网址http://example.com@evil.com
实际上意味着域example.com
上的用户名evil.com
。
但是,the username cannot contain the ?
(nor slash) character,因此您应该安全,因为您强制连接用户名。在您的情况下,URL变为:
http://example.com?@evil.com
或
http://example.com/?@evil.com
如果您在基本网址中包含斜杠(更好的做法)。这些都是安全的,因为它只是将您的网站evil.com
作为查询字符串值传递,因为解析器将不再将@evil.com
解释为域。
如果留下新行并且用户可以随意操纵HTTP标头,最糟糕的情况是什么?
这取决于您的http_get
函数在消毒值方面有多好。如果http_get
未在内部删除换行符,则攻击者可能会控制从您的应用程序发送的标头。
e.g。如果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中无效的其他参数。 See this question for list of valid characters