在 Android GCM(推送通知服务)注册过程中,我的移动客户端必须向Django视图发出POST 请求。默认情况下,视图需要 csrf_token ,但是可以使用@csrf_exempt 装饰器禁用它。
我的问题是:没有 csrf 检查视图的后果是什么?如果我从移动客户端(使用某种盐)编写令牌是否有意义?
在 Android GCM(推送通知服务)注册过程中,我的移动客户端必须向Django视图发出POST 请求。默认情况下,视图需要 csrf_token ,但是可以使用@csrf_exempt 装饰器禁用它。
我的问题是:没有 csrf 检查视图的后果是什么?如果我从移动客户端(使用某种盐)编写令牌是否有意义?
这实际上取决于您的观点的性质。
csrf 令牌用于帮助防止调用您在同一台 PC 上已通过身份验证时不打算执行的操作。例如,您的 Django 应用程序中存在一个 URL http://www.example.com/person/delete/356这将在您向其发布时删除 ID 为 356 的人。这可能正常,因为它需要身份验证才能触发它。但是,如果您在一个选项卡中登录了 Django 应用程序,并且有人向您发送了一封包含“http://www.example.com/person/delete/356”链接的网络钓鱼电子邮件(或类似电子邮件)——您点击它并且因为您已经在另一个选项卡中进行了身份验证,所以它可以工作。通过让 Django 期望一个 csrf 令牌,Django 只会处理它实际期望的请求 - 即 Django 知道它发出了令牌“12345ab”,因此当一个带有令牌“12345ab”的请求被返回时,如果它丢失了它的罚款。或者你发送“98765zx”它会失败。
如果您没有身份验证并且视图不执行任何操作(即它不更改数据,它只是显示它),那么创建@csrf_exempt 的风险非常低。
同样,如果这发生在移动应用程序中并且视图已通过身份验证,那么身份验证将不会在应用程序之间共享,因为它与浏览器选项卡一样,所以风险很低。
您还可以使用其他选项,在设置 HTTP 请求时,如果您能以某种方式获得预期的 csrf 令牌,那么您可以设置标头,就像在 AJAX 调用期间一样,请在此处阅读 Django 文档
这取决于许多因素,特别是除了注册 ID 之外您收集的内容,以及客户端如何连接到服务器以进行 POST。
攻击者可以将他自己控制的设备注册到受害者的帐户,并接收针对受害者的通知。
根据您正在做的事情,这可能不是那么糟糕,特别是考虑到 GCM 消息不应该包含任何敏感信息,而只是作为在更安全的方法下加载信息的触发器。
(即,如果 GCM 触发在客户端设备中加载基于身份验证的新页面的活动,由于攻击者的应用程序不会使用受害者的凭据进行身份验证,他们无法看到敏感信息)。
这比其他任何事情都更令人讨厌。
像 Nam 提到的那样设置一个令牌——如果您从服务器(即从 JavaScript 回调)启动 GCM 注册活动,只需设置一个客户端需要通过注册传回的令牌。CSRF 请求将与此步骤异步,并且由于缺少令牌而失败。
如果您的应用程序通过应用程序专有的子域(即 app.site.com 在子域级别具有身份验证 cookie)与服务器通信,只要应用程序专门加载您自己的域(即没有外部网站),并且服务器只允许访问该子域上的注册视图,因此很难被利用。CSRF 攻击很可能发生在浏览器中。
使用 CookieManager 从应用程序内的站点 cookie 中提取 CSRF 豁免值,并将其作为 POST 变量添加到请求中。然后你不需要让视图 CSRF 豁免。这本质上是 Django 处理 AJAX CSRF 的方式。请务必@ensure_csrf_cookie
在注册之前使用装饰器,以确保在客户端中设置了 CSRF cookie。
不过老实说,用于 GCM 注册的 CSRF 在“让您彻夜难眠的问题”图腾柱上极低。CSRF 更多是账户管理中的一个问题(例如更改密码、进行银行交易等)。