我已在此处询问有关IP身份验证的问题:TastyPie Authentication from the same server
然而,我还需要更多东西! IP地址可能非常容易欺骗。
场景:我的API(TastyPie)和客户端应用(在javascript中)位于同一服务器/网站/域中。我的用户没有登录。我想在我的javascript客户端使用我的API。
问题:如何确保(身份验证)我的 AJAX请求 来自同一服务器?
我正在使用Tatypie。我需要验证来自客户端的请求是在同一服务器/域等上进行的。我无法使用“登录会话”,因为我的用户没有登录。
我查看了私钥并生成签名,但他们可以在javascript中查看,使该方法不安全。如果我以某种方式请求服务器的签名形式(在某些python代码中隐藏私钥),任何人都可以向我的javascript发出的get_signature
发出相同的http请求,从而打败这一点。
我还尝试让Django视图将签名放在视图中,从而无需进行get_signature调用。这是安全的,但意味着我现在必须每次刷新页面以获得新的签名。从用户的角度来看,只有第一次调用API才能工作,之后他们需要刷新,再次毫无意义。
我无法相信我是唯一有此要求的人。这是我确定的常见情况。请帮助:)在Tastypie中使用自定义身份验证的示例也会受到欢迎。
由于
添加了:
答案 0 :(得分:7)
根据您的基础设施,@ dragonx的答案可能会让您最感兴趣。
my 2c
您想确保只有客户访问您的网站才能使用api吗?嗯机器人,机器人,爬虫与客户属于同一类别吗?还是我错了?如果你真的想要真正保护它,这很容易被利用。
我无法相信我是唯一有此要求的人。
也许没有,但正如您所看到的,您可能会对您的API产生多次攻击,这可能是某人不与您分享您的设计并使用auth更严格的安全措施的原因。
由于我们讨论的是AJAX请求IP部分与此有什么关系? IP 始终是客户的IP !所以可能,你想要一个公共API ...
我会使用令牌/会话/ cookie部分。
我会使用生成的令牌,持续一段时间以及下面介绍的流程。
我每次都会使用限制器like Github does。例如registered users
要解决刷新令牌的问题,我会这样做:
客户访问该网站
- >服务器生成 API TOKEN INIT
- >客户获得 API TOKEN INIT ,仅对启动1个请求有效。
客户端向API发出AJAX请求
- >客户使用 API TOKEN INIT
- >服务器检查 API TOKEN INIT 和限制
- >服务器接受请求
- >服务器传回 API TOKEN
- >客户端使用响应数据并存储 API TOKEN 以供进一步使用(将通过JS存储在浏览器内存中)
客户使用API启动Comm,以获得有限的时间或请求。请注意,您还知道init令牌日期,因此您可以使用它来检查页面上的第一次访问。
当客户端访问时,通过服务器生成第一个令牌。 然后客户端使用该令牌以获得真实的令牌,持续一段时间或其他限制。 这使得某人实际访问该网页,然后他可以访问API一段时间,请求可能等等。
这样您就不需要刷新了。
当然,如上所述,只有一个令牌和一个时间限制可以简化上述场景。
当然,由于您没有身份验证,因此上述方案很容易出现高级爬虫等。
当然,一个聪明的攻击者可以从服务器获取令牌并重复这些步骤但是,从那时起你就已经遇到了这个问题。
一些额外的分数
仅供参考GAE Cloud存储使用signed_urls用于相同目的。
希望它有所帮助。
PS。关于IP欺骗和防范欺骗攻击的防御维基百科表示不会将数据包返还给攻击者:
一些上层协议提供自己的IP防御 欺骗攻击。例如,传输控制协议(TCP) 使用与远程机器协商的序列号来确保 到达的数据包是已建立连接的一部分。自从 攻击者通常看不到任何回复包,序列号 必须猜测才能劫持连接。穷人 在许多较旧的操作系统和网络设备中实现, 但是,意味着可以预测TCP序列号。
答案 1 :(得分:6)
如果它是完全相同的服务器,您可以验证针对127.0.0.1或localhost的请求。
否则解决方案可能在网络级别,以便拥有可以检查的单独的私有子网。攻击者很难在不占用子网的情况下欺骗您的子网。
答案 2 :(得分:4)
我猜你有点困惑(或者我,请纠正我)。您的JS代码与API在同一服务器上发布并不意味着AJAX请求将来自您的服务器。客户端从您的服务器下载JS并执行它,这会导致从客户端发送对您的API的请求,而不是来自同一服务器。
现在,如果上述方案正确描述了您的情况,那么您可能要做的就是保护您的API不受bot scraping的限制。最简单的保护是CAPTCHA,您可以在Wiki页面上找到更多想法。
如果您担心其他网站可能会对您的API进行AJAX调用以复制您的网站功能,那么您不应该 - AJAX请求只能作为运行JS的页面发送to the same server,除非它是JSONP。
答案 3 :(得分:4)
简短回答:无法阻止专门的攻击者。
除了提供给您的信息之外,您无法识别客户。例如,用户名/密码身份验证的工作原理是只有有效的客户端才能提供有效的凭据。当有人登录时,您所知道的是有人提供了这些凭据 - 您假设这意味着这意味着他们是合法用户。
让我们在这里看看你的情景,据我所知。验证客户端的唯一方法是IP地址,very weak form of authentication。正如您所说,这很容易被欺骗,并且通过一些努力,您的服务器的响应可以被接收回攻击者的原始IP地址。 如果发生这种情况,您就无法采取任何措施。事实上,如果您假设某个有效IP地址的用户是有效用户,那么欺骗者和合法用户就无法区分。这就像有人窃取您的密码并尝试登录StackOverflow一样。对于StackOverflow,攻击者和你是无法区分的,因为他们只需要输入用户名和密码。
你可以像其他答案中提到的那样在客户端做一些奇特的事情,例如令牌,时间限制等,但是专门的攻击者能够模仿合法客户的行为,你将无法做到告诉他们,因为他们似乎都来自有效的IP地址。例如,在你的上一个例子中,如果我是一个想要进行API调用的攻击者,我会欺骗一个合法的IP地址,获取签名,并使用它来进行API调用,就像合法的客户端一样。
如果您的应用程序非常重要,可以将此级别的思想视为安全性,那么您至少应该考虑实现API令牌,公钥加密或其他比IP地址更安全的身份验证方法,以便将您的客户分开来自任何攻击者。通过IP地址(或其他易于伪造的令牌,如主机名或标题)进行身份验证,根本不会削减它。
答案 4 :(得分:3)
您可以通过同源政策
来实现这一目标答案 5 :(得分:3)
根据Venkatesh Bachu的建议,可以使用同源策略和http://en.wikipedia.org/wiki/Cross-Origin_Resource_Sharing(CORS)作为解决方案。 在您的API中,您可以检查Origin标头并做出相应的响应。 需要检查是否可以使用篡改数据等扩展来修改Origin标头。 确定的黑客仍然可以通过将浏览器指向本地代理服务器来窥探。
答案 6 :(得分:3)
如果此应用服务器在具有可配置侦听IP地址的普通Web服务器上运行,请将其设置为127.0.0.1。使用TCPServer模块,就像
SocketServer.TCPServer(("127.0.0.1", 12345), TheHandlerClass)
使用netstat
命令验证收听地址是否正确为“127.0.0.1”
tcp4 0 0 127.0.0.1.12345 *.* LISTEN
这将有效地使得在TCP级别上无法在同一主机之外发起任何连接。
答案 7 :(得分:2)
有两种通用的解决方案类型:使用普通Web服务器/客户端机制的带内解决方案,易于实现但有局限性;和带外解决方案,依赖于你在外部配置一些东西,需要更多工作,但没有带内限制。
如果您更喜欢带内解决方案,那么用于防止跨站点请求伪造(XSRF)的典型方法将很有效。服务器发出寿命有限的令牌;客户端在请求中使用令牌;通过使用HTTPS连接确保令牌的隐私(某种程度)。这种方法被广泛使用,并且运行良好,除非您担心可能拦截令牌的中间人攻击,或者可能将数据泄漏到其他客户端代码的错误浏览器。
如果您有动机,可以通过引入客户端证书来消除这些限制。这些是我们在Web服务器上使用的SSL证书的另一面 - 它们以相同的方式运行,但用于标识客户端而不是服务器。由于证书本身永远不会通过网络(您在浏览器或其他客户端本地安装它),因此您不会受到中间人和浏览器泄漏的相同威胁。此解决方案在野外使用不多,因为它设置起来很混乱(对于典型用户来说非常混乱),但如果您的客户端数量有限并且它们在您的控制之下,则部署和管理可能是可行的这个有限数量的客户证书。证书操作由浏览器处理,而不是在客户端代码中处理(即不在JavaScript中),因此您对在JavaScript中可见的关键数据的关注将不适用于此场景。
最后,如果您想跳过客户端配置废话,请使用最终的带外解决方案 - iptables
或类似工具来创建仅允许来自的会话的应用级防火墙您知道的网络接口(如本地环回)无法直接访问。