OAuth 的权限问题与信息隐忧

核心提示:以 QQ 登陆和微博登陆为代表的“一键登陆”背后不仅仅是登陆这么简单,它还默认获取了你的其他隐私资料和账号的部分使用权限,我们在享受便利的同时一定不要忘记保护好我们的个人信息安全。

去年3Q大战之后,开放几乎成为了最热的词汇,随后的国内互联网看似进入了开放平台的“蜜年”,各种基于开放平台的应用和社会化登录也随之出现。

将自身的产品和服务与大网站平台对接,不仅能省去注册等繁琐工作,不用为储存和传输大量的用户账号信息而烦恼,还可以迅速的带来流量、用户资源,并 得到更好的推广。而对于平台来说通过 API 支持协议可以得到很多的应用接入,可以为用户提供更多更好的服务。这对开发者和平台提供商来说是双赢的局面。因此,QQ 登录、各种微博登录和 SNS 登陆也似乎成为了第三方网站或应用的必备按钮。(在昨天腾讯宣布其QQ登录已经成为国内最大第三方帐号登录体系。)

本来利用已有的账号登陆这些第三方网站和应用是一件好的事情,因为从体验上来说可以方便用户,但是国内这些“一键登陆”真的是用户想的那样“一键登陆”吗?我们看到一个网站就用我们的账号登陆难道没有隐患吗? 这些”登陆“的背后的关键是什么?

如果你有够细心的话会发现所有登陆基本都是弹出一个对应对话框,其地址栏中也都会包含有“OAuth”字样。这说明,其当前采用的是 OAuth 协议。在目前,无论是国外还是国内,绝大部分都是采用 OAuth 协议来完成在第三方网站或应用的登陆的。

OAuth 是什么?它有什么优点呢?为什么都采用 OAuth?

OAuth(开放授权)是一个开放标准 ,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。via维基百科

OAuth 的优点

OAuth 不会使第三方网站或应用接触到用户的帐号信息(如用户名与密码),授权后的 http 通信中也不再传输用户信息而是以数字签名和访问令牌(Access Token)取代,即使截到数据包,也无法还原出用户的登录信息。这是OAuth 最大的优点,也是它得以逐渐成为现在通用的授权标准的原因。

OAuth 被普及的原因

对用户来说方便、安全;对中小第三方网站和应用来说,OAuth 可以使它们能够得到用户基本信息外的其他信息资料和账户部分使用权限;对大网站平台来说,OAuth 可以完美的解决用户的账户安全和开发者授权的平衡问题。因此 OAuth 协议确定后就获得了包括国外 Twitter、Facebook 和 Google 等认可,之后在国内也得到了有效跟进。

OAuth 授权的信息隐患

凡是只有其利就有其弊,OAuth 也不例外。为什么在安全上看似完美无缺的 OAuth 都有信息隐患呢?

1. 被滥用了的 OAuth 授权

OAuth 是一个授权(authorization)协议而不是认证(authentication)协议,因此,对于 OAuth 来说最大的信息隐患就是其本身。

OAuth 提供的是权限分配而非认证。在国内大多数网站的一键登陆根本没有去区分认证和授权 ,全部混淆为授权。本身用类似 OpenID 的简单认证即可完成的事情却非要走授权。而一键登陆在给用户带来便利的同时也带来了另一个弊端:用户变得越来越不在意自己的账号。因为 OAuth 协议本身的安全给了我们一种假象:别人获取不到我的账号密码,所以我的账户很安全。我们要明白,授权本身的实质相当于系统为第三方网站/应用开了一个后 门,而你的授权就是允许它们可以走后门进来获取你的隐私资料和使用权限。

打个比方就是,虽然它们不知道你家的锁长什么样,也没有你家的钥匙,但是人家就是能进得去你家,还可以看你家的电话簿,用你家的电话给你的亲朋好友 打电话等。很多其实扮演的只是抄水表的角色,在门外瞅一眼即可,但是偏偏国内那些平台们把水表安到了你家里面,这样很多抄水表的就可以打着抄水表的借口从 后门去你家向你的亲朋好友宣传它水表抄的好,想继续去你亲朋好友家抄水表。

譬如一些小游戏和星座信息之类的第三方网站和应用,无一例外都会要求我们授权给它们我们的好友关系、生日、相册、评论、甚至地理信息位置。对于我们 来说,个人信息的安全不仅仅是我们的用户名和密码,那些“被授权”的都是信息安全的一部分,甚至是最重要的部分。前几天通过 QQ 圈子我们也了解到了这些信息有多重要。

你授权的网站/应用越多,意味着越多的网站和应用能够接触到你的账户资料并拥有部分使用权限,也意味着隐患越多。虽然它们并没有获取到的你的账户密 码,虽然你之后从未登陆过或使用过它们,但是,除非你去隐藏很深的后台设置里面取消它们的权限,否则它们是一直能够接触到你的账户资料并拥有你账户的部分 使用权限的。

某种程度上说,OAuth 对我们个人信息安全来说是一扇隐形的窗户,而且这个窗户还是默认永久开放的。

2. OAuth 使用的不规范

在很多时候,出问题的环节往往不是技术,而是背后使用技术的人。

1. 平台 OAuth 部署不规范

OAuth 部署是否规范,例如有无强制使用 https 加密,有无强制部署 OAuth 2.0。对移动应用的授权有无注意应用会自建浏览器,有无注意在信息回传过程中的信息防护,这些都是需要考据的问题。OAuth 协议本身没有问题,但是对协议的用途是否规范值得商榷。

事实上,各开放平台之间的技术差异很大,因此每个平台使用并不是相同版本的协议,有 OAuth 1.0、OAuth 2.0 或混合的技术体系(甚至还有继续使用不安全的 Basic Auth)。此外,如果你去翻看一下国内各个开放平台的开发文档就会发现,虽然 OAuth 整体流程大致类似,但是对于授权的定义各家有各家的标准,对待开发者的态度各不相同,对授权的限制也是各家有各家的标准 ,对用户的账号保护也是各有各的说法。

例如某家开发平台上对待涉及自身利益的时候用“严禁”“禁止”字眼,而涉及用户账号利益的时候就变成了“不应”、“不鼓励” 等字样。再例如,对未审核应用、待审核应用和未通过审核应用的限制,国内只有两家平台对使用人数进行限制外,其他各家都只是稍微限制了一下调用频率次数和 不显示来源而已。

综合来看,国内的关于OAuth协议标准的实施部署是一个开发者和平台综合博弈的结果。

2. 应用开发者不自律

OAuth 的安全性相当一部分需要依靠应用开发者的高度自律,不该有的权限不去申请,但是事实并非如此。正常情况下,平时我们所用的 90% 的应用只需用只读权限即可,但是相反的是,只有 5% 的应用只拥有只读权限。对于开发者开说,尽量获取到用户账户的使用权限似乎是一种”追求“,而不管用不用得到。这不仅让人想起了 Android 移动应用上的普遍高权限。

3. 平台审核是否仔细

第三方网站或应用要接入平台需要通过平台的审核,审核是一层对开发者的把关。因为平台竞争的原因,各家审核标准并不一致,实际操作更是谁也不清楚。总体来看,强势的平台限制严格,弱势的平台因为要吸引开发者所以很多事情睁一只眼闭一只眼。

4. 用户对 OAuth 的不设防

OAuth 协议的实施很类似微软平台下软件的安装,用户经常在一步步的点击中默认”被授权“,因为国内大多数用户暂时还没有注意防护自己账户信息和权限的习惯。

我们该注意些什么?该怎么做?

1. 防止 OAuth 钓鱼登陆界面

注意观察弹出窗口是否为官方登陆域名,要谨防假冒钓鱼。

2. 授权之前的三思

在你将自己的账号权限授权给一个应用之前,先查清楚应用开发者的具体信息和他们的隐私保护条款,知道自己到底授权给了谁,到底给谁授予了哪些权限。

3. 定时清理你的第三方应用授权

要注意清理你的第三方应用授权,将那些无关紧要的或已经不再使用的第三方网站或应用取消授权,关上那扇隐形的窗户。

4.授权后注意其来源

授权第三方网站或应用后要注意查看其有没有通过官方平台的审核,如果来源显示来自”未审核应用“或类似字样后尽量先取消其授权,待审核通过后再进行授权。

未来,国内应该分区开认证和授权,给用户减少不必要的隐患,期待国内出现一个统一的OpenID(不像国外 OpenID 那样繁琐,或许类似 BrowserID 的东西),而不像现在,虽然号称一键登陆,但实际上许多第三方网站/应用在用户授权登录后,依旧有二次登录或重新注册等操作。

虽然目前这些隐患只是表现为偶尔的偷偷关注或偷偷以用户账号发一些广告,并没有爆发出严重的事件。但是想想那么多隐私信息和部分权限控制在那么多的第三方应用或平台上就有点不寒而栗的感觉。

服务的整合本来是大势所趋,也是未来方向,但是国内这些将认证和授权混为一谈的做法使得我们不仅没有更使得我们可以更方便更安全更省事的去管理,去获得服务,反而使我们的账户更加混乱,更埋下了信息安全的隐患。对此我们一定要提高警惕。

后记:在国外 OAuth 也没有太多安全可言,最近两天一个名为reference.me的社交服务就在滥用OAuth 协议,用户只要用 Google 账户授权登录就会自动向所有联系人发送邀请邮件,大家要注意。

时间: 2024-08-09 06:20:57

OAuth 的权限问题与信息隐忧的相关文章

权限管理系统 用户信息 --MyRapid 快速开发框架 Winform

1.1.2 用户信息 用户信息对用户信息进行登记,对于权限管理来说,这里只有用户编号具有意义,权限系统根据用户编号进行用户识别绑定.其他信息,例如:权限.部门.帐号类型等是框架所需要用到的属性,并不涉及权限管理,权限管理只会根据用户的角色分配功能模块以及页面按钮.

Java基础知识强化之网络编程笔记22:Android网络通信之 Android常用OAuth登录(获取个人信息)

1. 获取百度个人信息(使用Gson解析): 2. 代码案例: (1)工程一览图,如下: (2)activity_main.xml: 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent

微信 oauth授权 获取用户的信息

应用场景 (1)点击菜单直接链接跳转,这样直接跳是获取不到用户的openid的,需要用到这个 (2)获取用户的一些基本信息,头像,呢称,需要用到这个 准备 需要在公众号里面配置一个应用域名,不配置这个的话,跳转后就是空白页面 步骤 (一) //$callback="一个回调的网址比如http://www.baidu.com/auth.php"; $param ['redirect_uri'] = $callback . '&getOpenId=1';//&getOpen

Android 中运行时权限获取联系人信息 Demo

代码比较简单... AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="club.seliote.readcontact"> <uses-permission android:n

前后端分离进行权限管理之后端生成菜单和权限信息(二)

一.初始化菜单.权限信息 在进行用户名和密码验证成功后就进行权限和菜单的初始化,生成该用户的菜单和权限数据. class LoginView(APIView): authentication_classes = [] # 登陆页面免认证,其余的已经全局配置 def post(self, request, *args, **kwargs): ret = { "data": {}, "meta": { "code": 2001, "mess

Spring-Security-Oauth2 基于JDBC存储令牌和RBAC权限认证

相关配置来自李哥博客:  https://funtl.com/zh/spring-security-oauth2/   (本文仅记录自己学习记录,说的不详细,可以观看李哥博客) 认证服务器和资源服务器pom.xml配置  (李哥博客用的是tk.mybatis 我用的是spring  jpa) <dependencies> <dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP

译-BMC Remedy Action Request System权限控制概述

原文链接:Access control overview 说明: BMC Remedy Action Request System是BMC ITSM产品平台,简称AR 或者Remedy,可实现基于ITIL标准的整个IT管理流程的实施定制.该平台可实现多种权限级别的管理,包括人员.组.角色,以及表.字段.行级别等.本文可以用作其他对权限要求比较精细的系统参考. 为了便于理解,部分名词翻译如下: Server:服务器Form (or table):表单Field (or column):字段Acti

手动获取判断处理权限

主要用到的几个方法: //检查权限 int checkSelfPermission(String) //申请权限 void requestPermissions(int, String...) //是否应该显示请求权限的说明 boolean shouldShowRequestPermissionRationale(String) //处理权限结果回调 void onRequestPermissionsResult(int,String[],int[]) 是否有权限常量标识: PackageMan

django搭建微信后台——获取用户信息(7.20)

略坑啊,啃文档啃得要吐了,pythonanywhere上又不好看问题出在哪又跑到本地各种测试才知道原来要授权,又跑去N久之前弄的测试账号,总之各种坑...不过总算是弄清楚怎么实现的了,参考方倍工作室:微信公众平台开发(76) 获取用户基本信息. 第一步是要从POST过来的XML包里面获取openid,也就是FromUserName.这个在开发包里并没有不知道为啥,或者是我没发现?0.0总之自己写了一小段把这个值取出来了. def get_openid(data): if type(data) =