【发布时间】:2016-12-26 20:04:43
【问题描述】:
有时在解决生产中的错误时,能够从我的本地开发环境访问我们的生产 REST 服务器会很方便。但我担心将 localhost 添加到允许的来源会带来安全风险。搜索产生了相互矛盾的信息。我的担忧有效吗?为什么或为什么不?
【问题讨论】:
标签: rest security http webserver cors
有时在解决生产中的错误时,能够从我的本地开发环境访问我们的生产 REST 服务器会很方便。但我担心将 localhost 添加到允许的来源会带来安全风险。搜索产生了相互矛盾的信息。我的担忧有效吗?为什么或为什么不?
【问题讨论】:
标签: rest security http webserver cors
我假设你有
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://localhost
风险在于,在用户计算机上运行的任何服务都可能有效地绕过您网站的 Same Origin Policy。
所以如果你有一个 REST URL,比如
https://example.com/User/GetUserDetails
在用户计算机上运行的恶意或受损服务可以通过用户的浏览器发出该请求,然后获取有关用户的详细信息,因为他们的身份验证 cookie 将随请求一起传递。
现在,您可以争辩说,在用户计算机上运行的恶意服务可以直接从他们的浏览器中获取身份验证 cookie,然后自行发出请求。但是,如果服务本身存在一些缺陷(例如 XSS),这可能会允许另一个站点通过您的 REST 服务 (evil.example.org --XSS-> localhost -CORS-> example.com/User/GetUserDetails) 危害用户。
如果用户正在运行本地反向代理来访问某些内容,则可能会使您面临风险的另一种情况。如果目标站点是恶意的或被破坏,这将使目标站点能够通过您的用户危害用户。这是因为用户将访问域为localhost 的目标站点。
如果您确实需要这样做,我建议您为您的 REST 服务创建一个特殊的开发人员帐户,当您访问该帐户时,只会将 Access-Control-Allow-Origin: https://localhost 标头添加到您的请求中。这样一来,您就不会将其他用户置于危险之中,因为您知道您仅在 https://localhost 上运行前端服务器,因此您不会受到开放 CORS 设置的影响。
另一种方法可能是使用 noonewouldusethis2859282.localhost 之类的东西作为前端的本地副本。然后,您可以安全地添加 Access-Control-Allow-Origin: https://noonewouldusethis2859282.localhost 标头,因为没有其他人会使用它并且不会受到 CORS 攻击。
【讨论】:
GetUserDetails 是读取操作,而不是写入)。
在生产环境中将 localhost 添加到 CORS 设置没有安全问题。
通过添加类似的内容:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://localhost:3000
现在允许浏览器从 localhost:3000 调用您的服务,绕过 Same Origin Policy。任何 Web 开发人员现在都可以创建一个从他们的本地计算机运行的网页来调用您的 API,这对您的团队很有用。但是,localhost 不是publicly routable address - 您不能共享指向http://localhost:3000 的链接。请记住,CORS 只是一种针对 Web 浏览器调用您的站点的安全措施。任何人仍然可以通过服务器到服务器调用(或脚本)调用您的端点。但是,您应该避免:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
这将使您的网站可用于每个网站。相反,请将您的 Access-Control-Allow-Origin 锁定到需要它的站点。不幸的是,Access-Control-Allow-Origin 只接受一个值,因此您必须在服务器端处理 HOST 请求并返回有效值 (more info)。
当您发出需要身份验证的 CORS 请求时,您应该在调用中添加 Authorization 标头,而不是传递 cookie -
fetch does this by default。因此,对 COR 端点进行的任何调用都将通过 javascript 进行,将令牌添加到它仅用于该会话的标头中。如果您确实通过 cookie 或本地存储存储令牌,请注意它只能从该域 (more info) 访问。您的生产端点和 localhost 将不会有相同的 cookie 和共享本地存储。
最后,您可以通过使用 --disable-web-security (more info) 启动 Chrome,从 Chrome 向任何网站发出 CORS 请求。
最后,Google Chrome 仅允许服务人员在安全网站和http://localhost 上运行。如果您选择创建一个 local.example.com 用于开发,则需要创建一个 SSL 证书并在本地计算机上进行所有配置以使其运行。我建议只使用http://localhost:XXXX。
【讨论】: