专栏首页FreeBuf为什么说你的API并不安全?

为什么说你的API并不安全?

0×00 背景介绍

前段时间我向Spree Commerce公司报告了其所有API路径存在 JSONP+CSRF漏洞的问题。同样,Instagram的API存在CSRF漏洞。Disqus、Stripe和Shopify的API通过JSONP泄露隐私信息。这一切问题的根源都是没有合理使用混合API认证。

希望所有API开发者都能看一看这篇文章。我将解释API认证的基础和目前业内最好的做法。

0×01 过程详述

首先你的API通过api_key来进行认证:

def load_user @current_api_user = Spree.user_class.find_by(spree_api_key: api_key.to_s) end

这时有人让你启用CORS(跨域资源共享,Cross-Origin Resource Sharing),因为他们想通过JS调用你的API:

config.middleware.insert_before 0, "Rack::Cors" do allow do origins '*' resource '*', :headers => :any, :methods => [:get, :post, :options] end end

显然在你的APIController中有skip_before_action :verify_authenticity_token。那么你会说对于来自比如Android app的API请求为什么还需要CSRF验证呢?

还有一位开发者希望你能加上JSONP(JSON with Padding)的支持因为低版本浏览器不支持CORS。你觉得这当然没问题:

after_filter :set_jsonp_format def set_jsonp_format if params[:callback] && request.get? self.response_body = "#{params[:callback]}(#{response.body})" headers["Content-Type"] = 'application/javascript' end end

目前看来一切都没什么问题。最后你的开发者决定追随Backend-As-API的潮流并在客户端使用你的api.example.com。这时有两种选择:

一. 手动增加api_token

比如说Soundcloud的每个API请求头部使用Authorization:OAuth 1-16343-15233329-796b6b695d2c7c1,Foursquare使用oauth_token=YXIAC4Y254HGZBNPQW6S0UFBGGSU57RBP。

这样做的缺点:

1.XSS。OAuth tokens可通过JS访问,攻击者可借此泄露受害者凭证。可以使用HttpOnly flag来防止此类事件发生。但OAuth tokens并没有此类预防措施。 2.对于每个请求都会有OPTIONS请求,增加了潜在风险。

尽管很多人使用这样的方法但我并不推荐。

二. 通过cookie认证用户

这样一来你想到修复方法很简单:

@current_api_user = (try_spree_current_user || Spree.user_class.find_by(spree_api_key: api_key.to_s))

try_spree_current_user 解析 _spree_session cookie, 得到user_id返回User.find(session[:user_id])。那么这种做法有什么问题呢?

类似“授权(Authorization)”,cookie也是封装在头部,但即使是经验丰富的开发也不一定能真正理解cookie。我称其为“自带凭证(sticky credentials)”,因为它们是自动加上的,即使是来自第三方域的请求(比如evil.com)。

因为绝大多数web开发者并没有理解到这样的概念导致CSRF成为全球最普遍的安全问题。这也是为什么所有基于cookie的认证都需要用额外的csrf_token nonce进行双重认证。这个nonce能使你确定请求来自你的域名。

1.因为你的API请求漏掉了CSRF保护,所有你的API路径都有请求伪造的风险。 2.JSONP通过跨站泄露GET响应。 3.CORS就更不可靠了,每种请求都会泄露信息。

0×02 解决方案

那么怎么做才对?混合API认证:

@current_api_user = unless api_key.to_s.empty? Spree.user_class.find_by(spree_api_key: api_key.to_s) # Good to go! else # Everyone stand back, we are using cookies! # 1) verify CSRF token for all non-GET requests # 2) drop JSONP support # 3) drop CORS support try_spree_current_user end

这种混合的方法允许前端(JS/HTML app)和第三方应用使用你的api.example.com,让你的凭证不受XSS(HttpOnly)的困扰,也不会产生并无必要的OPTIONS请求。上述介绍的就是目前业内的最好方法。

*原文地址;sakurity,编译/florence,转载请注明来自FreeBuf黑客与极客(FreeBuf.COM)

本文分享自微信公众号 - FreeBuf(freebuf)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2015-12-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Android优化之Hardware Layer

    项目中越来越多的动画,越来越多的效果导致了应用性能越来越低。该如何提升。 ###简介 在View播放动画的过程中每一帧都需要被重绘。如果使用view l...

    xiangzhihong
  • Scroller简介

    Scroller简介 在SlidingMenu项目中为了实现控件的滑动,需要用到Scroller类来实现缓慢的滑动过程,至于有人说View类可以直接调用scro...

    xiangzhihong
  • 人工智能的语言-PYTHON

    1989年的圣诞节33岁的荷兰人Guido van Rossum很是无聊,看完《Monty Python飞行马戏团》后,思绪便信马由缰地乱跑起来,脑子有一个声音...

    企鹅号小编
  • Android四大组件之Service

    Android四大组件之Service 服务的两种开启方式: startService();开启服务. 开启服务后 服务就会长期的后台运行,即使调用者退出了....

    xiangzhihong
  • Android入门之动画

    Android动画 AlphaAnimation RelativeLayout rl_splash = (RelativeLayout) findViewBy...

    xiangzhihong
  • Android入门介绍

    Android入门介绍 3G、4G 第三代移动通信技术(3rd - Generation),速率一般在几百Kbps,较之前的2G和2.5G在数据传输速度上有很大...

    xiangzhihong
  • 物联网中的大数据架构、应用案例以及带来的好处

    作者:周硕彦 第一节 简介 近年来“物联网”(IoT)和“大数据”是两个最受瞩目的话题。在物联网的概念里,有关任何开和关切换到网络的设备皆会彼此连接,它们之间都...

    企鹅号小编
  • ListView专题

    ListView专题 1.ListView属性: fadingEdge属性 ListView上边和下边有黑色的阴影,android : fadingEdge ...

    xiangzhihong
  • Android四大组件之ContentProvider

    Android四大组件之ContentProvider ContentProvider 安卓应用程序默认是无法获取到其他程序的数据,这是安卓安全学的基石...

    xiangzhihong
  • Android资源混淆打包方案

    概述 我们知道在Android的打包过程中,有一个步骤是压缩,也是为了减少apk包的大小,其中在压缩的过程中,很大一部分就是对资源的压缩,除了系统的压缩方案之外...

    xiangzhihong

扫码关注云+社区

领取腾讯云代金券