我已经阅读了有关特定于 Web 的攻击和预防的多个主题,但我仍然不确定我是否明白这一点。
假设我们有一个网站 ( myapp.com) 和一个 Web 服务 ( myapi.com)。webapp 和服务使用 JSON 交换数据。
服务
该服务有一些受限操作。要访问其中任何一个,用户必须使用用户名/密码对登录。(密码在存储到数据库之前经过哈希处理。)当登录请求有效时,将随机生成的令牌发送回调用者,并且其哈希版本与登录用户的 id 一起存储在数据库中。(随机令牌生成必须很强,因此无法猜测。)每次需要访问受限操作时,都必须为上面的令牌设置特定的标头,并且必须由调用者发送。这样,服务可以验证一个/哪个用户登录(通过散列令牌和搜索数据库实体)。
网站/webapp
当一个有效的登录请求被 POST 到服务时,接收到的令牌被存储在会话中。每次客户端(浏览器)想要访问受限页面时,应用程序都会检查令牌是否可用(如果找不到令牌,则重定向到登录页面)。然后它将每个请求发送到服务,并将所需的标头设置为存储在会话中的令牌。
CSRF 攻击
有一个邪恶的站点 ( evil.com) 想要(例如)修改受害者的密码。可能有 3 种不同的通信线路:
evil.com -> myapp.com
GET/POST:这两个请求似乎都可以,因为 myapp.com 需要一个带有会话 id 的 cookie 才能从会话中读取令牌。而且因为不是 evil.com 提供的,所以会被重定向到登录页面。(evil.com 可以提供会话 ID,但首先,它必须设法获取其他人的 ID。)
evil.com -> myapi.com
GET/POST:这两个请求似乎都可以,因为 Web 服务需要一个包含有效令牌的标头。(和以前一样,evil.com 可以在标头中发送一个有效的令牌,但首先,它必须获得一个。)
evil.com -> victim
GET:基本上看起来没问题。即使 evil.com 设法通过受害者向 myapp.com 创建 GET 请求,也不会发生任何事情(除了受害者会收到一个 HTML 页面)
POST:这是真正的危险(据我所知),因为 evil.com 可以通过受害者的浏览器发送 POST 请求(例如,通过自动提交带有隐藏输入的表单),它发送 cookie(包括会话 ID)请求,因此 myapp.com 将用户的令牌设置为标头,最后,服务执行操作。
我为此制作了一个漂亮的(开玩笑的)图表:
如何防止 CSRF 攻击
我打算检查它们是否存在原产地/引荐来源标头。如果请求来自完全不同的站点,则可以拒绝它而无需检查其他任何内容。但据我所知,这些标题并不总是存在。这就是为什么我们必须进行某种验证。或者原产地检查的缺点是什么?
当myapp.com生成包含 a 的 HTML 视图时form,它还会添加一个隐藏输入,其中包含存储在会话中的令牌值。这样,当POST接收到请求时,myapp.com它可以验证隐藏的输入是否可用,并且还可以将其值与会话中存储的值进行比较。并且由于evil.com无法读取受害者的 cookie,因此无法猜测所需的隐藏字段。
AJAX 呢?
还有别的事吗?
由于我只是触及网络安全世界的表面,我不确定这里是否还有其他可能导致问题的东西。例如,是否有任何额外的标头可用于保护应用程序?不支持某些建议解决方案的旧浏览器怎么办?如果您能提供一些可以突破这种防御的示例(最好是解决方案或关键字),那将是最好的。
附带说明:我对 php、Java(JSP、Servlet)和 C#(ASP.NET)很感兴趣(并且有一些经验)。这些可能(并且可能)具有不同的内置安全级别。我知道有多个受信任的框架,但我的意思是了解这些东西,而不仅仅是有一个“drop and it works”的解决方案。
相关文章:
