随着微信微博等社会化媒体的火热,第三方登录迅速成为一种快捷注册的方式,社会化分享也成为一种知识快速传播的渠道。在移动端,几乎大多数应用都接入了第三方登录或者分享组件,尤其是微信、QQ、微博三大巨头。这三者都提供了开放平台和SDK来帮助开发者接入这些功能,然而这些真的安全吗?


一、漏洞发现

先说说场景吧,由于业务要求,需要对分享控件做了一次大的升级和重构,然后发现我们分享组件使用的是第三方的ShareSDK(专门封装分享API的组件,大部分童鞋应该都听说过),这本来也没什么问题。

然后,重构过程中遇到一个难以理解的事情,在工程assets目录下面有一个名为ShareSDK.xml的文件,在打开这个文件之后,我震精了,喝到口的咖啡全喷到了键盘上,文件内容是这样的:

第三方开放平台的应用注册信息都是明文写在这个文件中的,包括重要的AppId和AppSecret(图内容来自是ShareSDK官方demo)。这个时候,第一个考虑的问题还仅仅是隐私暴露,并没有考虑到安全漏洞方面。

当然,接下来就去看这样设计的原因,原来是ShareSDK内部调用第三方应用授权分享需要这些应用注册信息,为了方便开发者接入,所以采用这种文件静态注册的方式。

作为一个开发者老司机,无论是直觉上还是开发原则上,都隐隐觉得这种方式是有严重问题的。为什么呢?因为assets目录在打包过程中是原封不动地打进APK包内的,任何人不需要任何反编译工具就能直接从APK包内提取出来。那么,如果直接提取出来放到另一款应用中是不是意味着……

想到这里,已经惊出一身冷汗了,世纪大坑!世纪大坑!世纪大坑啊!

接下来就是验证的过程,步骤非常简单。
1、找到一款接入ShareSDK组件的应用,将其安装包APK内的ShareSDK.xml解压提取出来。
2、直接将项目的ShareSDK.xml替换为上一步的文件。
3、调用分享

验证结果:除了微信相关的不能分享,QQ和新浪都分享成功了,并且显示分享内容来自XX应用,XX应用就是我们提取的那款应用了。


二、漏洞原因

当然,如果仅仅是这样,只能说是小漏洞,波及范围并不广。可惜事与愿违,市场上90%以上的应用都在受灾范围内,原因后面分析。

为了帮助理解,我们先来谈一谈社会化分享的机制。

首先,一款应用要接入社会化的授权登录分享等功能,需要到开发平台上去注册应用信息,注册信息包括应用包名,应用签名等等,以微信为例:

接着,应用注册成功后,我们会得到两个key,一个是AppId,一个是AppSecret(或AppKey):

当然,一般情况下,移动应用只需要AppId,而AppSecret主要是用在接口API调用。为了安全起见,微信开放平台都已经不再存储AppSecret,可想而知这些信息有多重要,所以在大家项目中无论是写在Java代码里还是配置在xml中,只要是明文,都是万万不可行的!

那么,第三方调用的机制流程是怎样的呢,以微信为例:

步骤1:项目应用中集成微信SDK,也就是libammsdk.jar。
步骤2:通过AppId调用微信SDK发送请求,比如登录授权、分享等。
步骤3:微信SDK将AppId、当前应用包名、请求信息发送到微信客户端。
步骤4:微信客户端接收到AppId后,请求服务端得到我们注册在开放平台的应用包名、应用签名、权限等。
步骤5:微信客户端比对注册的应用包名和步骤3中的应用包名,不一致调用失败。
步骤6:微信客户端比对注册的应用签名和请求应用的签名(通过步骤3中的应用包名调用系统API查询),不一致调用失败。
步骤7:调用相应的API,比如登录授权、分享等,当然还要看注册的应用是否有这些权限。

其中最关键是步骤5和步骤6,正是因为有了这两步的包名和签名校验,所以之前验证漏洞时微信分享调用失败。

新浪微博和QQ的第三方调用机制流程大同小异,但是QQ完全不做包名和签名校验,也就是省略了步骤5和步骤6,所以验证漏洞时分享成功。

新浪微博比较特殊,因为其除了客户端调用还是支持网页端调用,所以验证漏洞时调用客户端分享失败,调用网页端分享成功。

综上所述,校验包名和校验签名是防止恶意调用的防御手段,QQ和新浪微博网页这种不做校验的方式都是存在安全隐患的,只需要知道特定应用的AppId,就可以以其名义发起恶意的授权登录分享。遗憾的是,很多开发者不清楚AppId的重要性,直接暴露在代码或文件中。


三、漏洞升级

前面说了,事情并不仅仅是这么简单。校验包名和校验签名是防止恶意调用的防御手段,但是这种防御是否真的有用呢?

我们再来仔细梳理下流程,同样以微信为例:

步骤3:微信SDK将AppId、当前应用包名、请求信息发送到微信客户端。
步骤5:微信客户端比对注册的应用包名和步骤3中的应用包名,不一致调用失败。
步骤6:微信客户端比对注册的应用签名和请求应用的签名(通过步骤3中的应用包名调用系统API查询),不一致调用失败。

这是其中最关键的三个步骤,微信客户端接收到的AppId、应用包名都是来自微信SDK,而应用签名是通过应用包名调用系统API获取的,所以实质上校验的来源只有AppId和应用包名两个。

这里面有一个非常重要的但又非常容易忽略的点就是:系统查询到的应用签名,可能并不是发起调用的应用,而是手机上安装的指定包名的应用。 换言之,步骤3中发送到微信客户端的AppId和应用包名,如果就是被恶意攻击的应用的AppId和包名,并且手机上装有这款被攻击的官方应用,那么步骤5和步骤6就全部被绕过了。

剩下的难点就是如何通过第三方SDK发送指定的AppId和包名给第三方客户端了。

AppId容易得到,市场上几乎所有应用里面接入的社交化AppId都是明文形式写在代码里面的,比如AndroidManifest.xml(天坑!天坑!天坑!)。

最后一步就是伪装包名了,在Android中获取当前应用包名都是通过Context.getPackageName的方式,开发者调用SDK的时候传入的参数就有这个Context,那么事情就变得无比简单了!

另外,还有第二种方式,因为最终都是通过startActivity的方式调起第三方应用,参数都是通过Intent传递,我们可以在startActivity前将Intent中的参数包名替换掉,思路差不多,在此略过。

所以,只需要获取到指定应用的包名,第三方AppId,就可以伪装成这款应用发起第三方调用,而包名和AppId都是极其容易获取的,当然为了绕过签名校验手机还必须装有这款指定的官方应用。

下面,测试了国内几款接入微信分享功能的知名应用,截图如下:


四、漏洞危害

说完了漏洞,下面就要说这款漏洞的危害了,当然开发者节后也有的忙活了。

1、用户隐私盗取

很多应用程序都接有第三方登录授权的功能,有利于简化用户注册过程。利用这个漏洞,攻击者可以伪装成官方应用骗取用户授权,而且授权页面是真真正正的授权页,上面也确实显示的是真正官方应用的logo和应用名。

授权成功之后,攻击者拿到openId和access_token之后,再结合AppId和AppSecret,很容易就获取到用户的社交隐私,甚至如果抓包到接入第三方登录功能应用的登录接口,你的相关应用隐私也就一览无余了。

相对来说,微信授权登录还是比较安全的,因为授权结果是回调到WXEntryActivity的,由于应用applicationId的关系,回调的WXEntryActivity是难以被伪装的,所以暂时还未想到其它攻击手段,但依然是隐患。

2、虚假分享

和登录授权不同,分享是不需要数据回调的,直接就分享出去了,那么利用这个漏洞的可操作性就高了,而且非常简单。

攻击者可以给微信好友(群组)、朋友圈、QQ好友(群组)和新浪微博上肆意分享危害性质的信息网站链接,而在这些社交应用里面,会显示来自XX应用。比如利用此漏洞分享虚假新闻(来自XX头条),分享虚假视频(来自XX视频),分享虚假话题(来自X乎),分享红包优惠券(来自X东)等等。由于社交应用里面显示的是来自官方应用,所以可信任度非常高,真假难辨,骗取用户点击的几率可谓是100%,如果是钓鱼链接,后果难以想象。


五、漏洞反思

经过数个小时的测试,目前市场上主流应用都在此漏洞危害范围之内,几乎被全军尽墨,能够幸免的应用屈指可数,想想背后都是一身冷汗。

关于这个漏洞,从两个层面来分析下修复策略吧。

1、开发者

这个漏洞原理并不复杂,其中一个重要的因素就是开发者直接暴露出去AppId甚至AppSecret,由于开发者安全意识不够,未认识到它们的重要性。直接的后果就是暴露出去无法收回,即使后面版本处理了,历史版本里面仍然可以查到,可谓亡羊补牢为时晚矣!虽然这种事情难以避免,但仍然需要给我们一个血淋淋的教训。在此,总结出以下两点:

a、严禁明文暴露注册第三方平台的AppId、AppSecret,包括文件、代码、接口,至少要做一层简单的加密。
b、接入ShareSDK授权登录或分享的,必须在代码中动态注册AppId、AppSecret,同样代码中明文用的也应该是加密后的值。

2、第三方开放平台

首先,鄙视下手Q,竟然连包名和签名都不校验,也不知道是为了简化开发者接入流程还是其它原因,这不是坑爹么。

对于微信和新浪微博等开放平台,需要重新思考下校验机制,目前的包名+签名校验方式肯定是不安全的了,当然现在是不可能整体更换方案了,修复针对点是保证授权分享调起者是真正的官方应用。个人有以下几点建议:

a、增加Context的校验,防止使用自定义的Context伪装包名(最简单)。
b、授权登录回调禁用广播监听器等方式,使用指定Activity启动回调,难以被拦截和伪装,类似微信这种。
c、接口API调用严禁明文暴露调用发起者的AppId、AppSecret,比如微信授权时chromium的log就能抓到这些信息。
d、需要重视AppId,同时督促开发者保护好这些重要数据。

综上所述,强烈建议开发者按照以上几点排查和处理,同时希望第三方开放平台尽快更新SDK和客户端,修复此漏洞。

最后,祝各位国庆节日快乐!


本博客不定期持续更新,欢迎关注和交流:

http://blog.csdn.net/megatronkings

全军尽墨的Android应用:社会化授权登录及分享安全漏洞相关推荐

  1. 【Android应用开发详解】第01期:第三方授权认证(一)实现第三方授权登录、分享以及获取用户资料

    转载请注明出处:http://blog.csdn.net/yangyu20121224/article/details/9057257 由于公司项目的需要,要实现在项目中使用第三方授权登录以及分享文字 ...

  2. 使用share SDK实现QQ空间授权登录、分享(1.x版本)

    随时随地技术实战干货,获取项目源码.学习资料,请关注源代码社区公众号(ydmsq666) 操作步骤: 1.在share官网注册应用生成AppKey并下载SDK     网址:广州掌淘网络科技有限公司 ...

  3. Android应用实现微信登录与分享

    Android应用实现微信登录与分享 1. 闲话(可直接无视 项目慢慢的推进,逐渐的做到了微信第三方登录的功能模块了.其实我想说Orz,我等这一天等了好久了,想做个微信验证登录都等了两个多星期咧(其实 ...

  4. Android:微信授权登录与微信分享全解析

    前言 在移动互联网浪潮中,联网APP已经把单机拍死在沙滩上,很多公司都希望自家应用能够有一套帐号系统,可是许多用户却并不一定买账:我凭啥注册你家应用的帐号?微博,微信,QQ几乎成了每个人手机中的必装应 ...

  5. android qq授权申请appkey,手把手带你集成友盟实现授权登录、分享

    android.jpg 集成准备(获取AppKey) 第一步.png 第二步.png 第三步.png 第四步.png 第五步.png 第六步.png 这里就可以拿到友盟的AppKey了接下来集成友盟 ...

  6. Android之QQ授权登录获取用户信息

    有时候我们开发的app需要方便用户简单登录,可以让用户使用自己的qq.微信.微博登录到我们自己开发的app. 今天就在这里总结一下如何在自己的app中集成QQ授权登录获取用户信息的功能. 首先我们打开 ...

  7. Android 集成facebook授权登录以及过程中登录错误,密钥散列不匹配

    Facebook开发文档 授权登录还是比较简单的,看着文档一步步下来就好.集成登录的代码也较少,直接在登录的activity写即可. 主要说下可能会遇到的问题: 授权登录出现: 应用程序未设置:此应用 ...

  8. 智汀云盘-开发指南android端:授权登录

    授权登录功能的实现主要是通过智汀云盘App发起一个携带要获取权限参数的意图去启动智汀App,智汀App根据权限参数获取相应的授权信息(包括家庭信息.用户信息和登录凭证)并通过广播发送消息,智汀云盘接收 ...

  9. 关于Android如何集成QQ登录及分享

    首先去友盟进行下载压缩包 然后使用友盟集成工具 将umeng_integratetool_result里的东西拷贝到工程中 新建一个app继承Application,去清单文件里面注册 在oncrea ...

最新文章

  1. win10 vs2015 编译caffe2
  2. A02 创建实验环境快照
  3. 线性方程组与基尔霍夫定律
  4. VS 2005/2008 开发工具中 使用正则表达式查找替换的使用说明
  5. 淘宝 oracle mysql_Oracle 与 MySQL 的区别-阿里云开发者社区
  6. ESP32,使用gitee搭建 ESP-IDF 开发框架
  7. 顺序图中页面、窗口等为什么当做类处理?
  8. html/jquery最实用功能与注意点
  9. 继续!从顶会论文看对比学习的应用!
  10. FlowNet: Learning Optical Flow with Convolutional Networks
  11. c语言中闰年的流程图_c语言程序设计流程图怎么画?具体有什么规范,有知道的吗...
  12. 来自太阳,爱情的故事,生存和欢乐的影子上升 - 免费节选
  13. ubuntu linux 从入门到精通.pdf,UBUNTU LINUX从入门到精通(附DVD)
  14. 为什么登录赛尔号显示服务器未开启,赛尔号之勇者无敌无法打开怎么办 赛尔号之勇者无敌登录不了解决方案...
  15. Android JNI开发笔记二:动态库和静态库
  16. 杭州配眼镜大调研:各年龄段如何配到高性价比眼镜?去哪配镜?
  17. python模拟登陆微博_超详细的Python实现微博模拟登陆,小白都能懂
  18. opencv项目实践二(银行卡卡号识别)
  19. Ubuntu16.04建立共享文件夹
  20. CDH和CM介绍及搭建

热门文章

  1. oracle 按旬统计并且每月小计 行转列 PIVOT函数 与分组小计 ROLLUP 函数
  2. python中的除法,取整和求模
  3. Patches Are All You Need?
  4. Long与Integer之间的转换产生的问题
  5. “如果没有从事研发,学习自动化的我可能在装水表”
  6. 分布式计算框架MapReduce架构
  7. Visual Studio2012安装失败
  8. 什么是登陆器劫持登陆器劫持怎么办GOM引擎的登陆器会被劫持吗
  9. createCriteria用法
  10. React.createRef()的使用