我正在使用Flask,需要获取用户的IP地址.这通常通过request.remote_addr完成,但由于此应用程序托管在第三方(并使用cloudflare),它只返回localhost.
Flask建议获得X-Forwarded-Host但是他们立即说这是一个安全风险.有没有一种安全的方法来获得客户端真正的IP?
这里的问题不是ProxyFix本身会导致用户访问您的系统,而是ProxyFix将采用曾经最可靠的信息并用可能不可靠的信息替换它.
对于初学者,当您不使用ProxyFix时,很可能从TCP数据包中的源IP地址检索REMOTE_ADDR属性.虽然并非不可能,但TCP数据包中的源IP地址很难欺骗.因此,如果您需要一种可靠的方法来检索用户的IP地址,REMOTE_ADDR是一种很好的方法.在大多数情况下,你可以依靠它为你提供准确的东西request.remote_addr.
当然,问题是在反向代理情况下,TCP连接不是来自最终用户; 相反,最终用户与反向代理建立TCP连接,然后反向代理与您的Web应用程序建立第二个TCP连接.因此,request.remote_addr您的应用中将具有反向代理的IP地址而不是原始用户.
ProxyFix应该解决这个问题,这样你就可以request.remote_addr拥有用户的IP地址而不是代理.它通过查看远程代理(如Apache和Nginx)添加到HTTP头(X-Forwarded-For)中的典型HTTP头并使用它在那里找到的用户IP地址来实现这一点.请注意,Cloudflare使用不同的HTTP标头,因此ProxyFix可能无法帮助您; 您需要编写自己的中间件实现才能request.remote_addr使用原始客户端的IP地址.但是,在本答复的其余部分中,我将继续将该修复称为"ProxyFix".
然而,该解决方案存在问题.问题是虽然TCP标头最可靠,但HTTP标头不是; 如果用户可以绕过您的反向代理并将数据直接发送到服务器,他们可以在HTTP标头中放置他们想要的任何内容.例如,他们可以使HTTP标头中的IP地址成为其他人的IP地址!如果使用IP地址进行身份验证,则用户可以欺骗该身份验证机制.如果将IP地址存储在数据库中,然后将其在应用程序中以HTML格式显示给另一个用户,则用户可能会将SQL或Javascript注入到标头中,从而可能导致SQL注入或XSS漏洞.
所以,总结一下; ProxyFix采用一种已知的最安全的解决方案,从TCP数据包中检索用户的IP地址,并使用解析易受欺骗的HTTP标头的非常安全的解决方案将其切换.
因此,在反向代理情况下仅使用ProxyFix的建议意味着:如果您接受来自非代理的位置的连接,请不要使用此方法.这通常意味着让反向代理(如Nginx或Apache)处理所有传入流量,并让您的应用程序在防火墙后面实际使用ProxyFix.
您还应该阅读这篇文章,其中解释了ProxyFix过去是如何被破坏的(尽管现已修复).这也将解释ProxyFix如何工作,并为您提供有关如何设置num_proxies参数的想法.
假设您的用户位于A点,他们将请求发送到Cloudflare(B),最终将请求发送到您的最终应用程序(C点).Cloudflare将发送A的IP地址CF-Connecting-IP header.
如上所述,如果用户找到指向C的IP地址,他们可以直接向C点发送特制的HTTP请求,其中包括他们想要的任何标题信息.ProxyFix将使用其逻辑来确定HTTP头中的IP地址,如果您依赖该值,那么这当然是有问题的.
因此,您可能希望查看类似mod_cloudflare的内容,它允许您直接在Apache mod中执行这些代理修复,但仅限于HTTP连接来自Cloudflare IP地址(由TCP IP源定义).您也可以只接受来自Cloudflare的连接.有关详细信息,请参阅如何将原始访问者IP还原到我的服务器日志,并帮助其他服务器(如Nginx)执行此操作.
这应该给你一个开始.但是,请记住,您仍然不是"安全":您只关闭了一个可能的攻击向量,并且该攻击向量假定攻击者知道您的实际应用程序的IP地址.在这种情况下,恶意用户可能会尝试使用欺骗性Cloudflare IP地址进行TCP攻击,尽管这非常困难.更有可能的是,如果他们想要造成严重破坏,他们只会DDOS你的源服务器,因为他们绕过了Cloudflare.因此,在保护您的应用程序时还需要考虑更多的事情.希望这有助于您了解如何使一个部分更安全.
| 归档时间: |
|
| 查看次数: |
3374 次 |
| 最近记录: |