前置信息

JWT的组成

介绍JSON Web Token

  • JWT由3部分组成
    • Header
    • Payload
    • Signature
JWT由3部分组成 它们经过编码后 用`.`作为连接符号 拼接成一个JWT. 一个JWT的格式如下:
Base64Urlencode(Header).Base64Urlencode(Payload).Signature

比如这个JWT:
eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE1ODY1MjUyNzcsImFkbWluIjoiZmFsc2UiLCJ1c2VyIjoiSmVycnkifQ.BWbSmWbTfsJBc5YMaKCXY4SlvxPZXuobf4vfAFJEXu00qC5nXeyA7csmC7PErf5YoxmbDzFVPobnzhndFe10xQ

分解为3部分:
Header:    eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9    --Base64Urldecode->    {"alg":"HS512","typ":"JWT"}

Payload:   eyJpYXQiOjE1ODY1MjUyNzcsImFkbWluIjoiZmFsc2UiLCJ1c2VyIjoiSmVycnkifQ    --Base64Urldecode->    {"iat":1586525277,"admin":"false","user":"Jerry"}

Signature: BWbSmWbTfsJBc5YMaKCXY4SlvxPZXuobf4vfAFJEXu00qC5nXeyA7csmC7PErf5YoxmbDzFVPobnzhndFe10xQ

什么是Sign in with Apple

参考官方开发者资料 https://developer.apple.com/sign-in-with-apple/get-started/

什么是Sign in with Apple: 个人简单概括就是,它是苹果官方提供的授权功能,苹果用户使用自己的Apple ID登录成功后,可以登录支持“Sign in with Apple”的第三方APP和网站,且更安全、更能保护隐私。

Sign in with Apple的优点

参考官方资料 https://support.apple.com/en-us/HT211687

主要关注一下"隐私和安全性"方面的优点:

“通过 Apple 登录”功能让您能够使用现有的 Apple ID 登录第三方 App 和网站,不仅快捷轻松,而且更加私密。

  • 用户使用“Sign in with Apple”登录第三方APP时,第三方APP的开发者能获取到哪2个用户信息?
    • 用户的“姓名”
    • 用户的“电子邮件地址” (Apple的“私密电子邮件中转服务”,使用户可将这个“电子邮件地址”保密,同时接收到电子邮件。)

您在参加计划的 App 或网站上看到“通过 Apple 登录”按钮,说明您可以使用自己的 Apple ID 来设置一个帐户。您不需要使用社交媒体帐户、不必填写表单、不必另外设定新密码。

“通过 Apple 登录”这个功能的设计初衷就是为了尊重个人隐私,让您能够掌控自己的个人信息。这个功能可以在 iOS、macOS、Apple tvOS 和 watchOS 上以及任何浏览器中作为原生功能使用。

  • 隐私和安全性
    • 在您首次登录时,App 和网站只能要求获取您的“姓名”和“电子邮件地址”来为您设置帐户。
    • 您可以使用“隐藏邮件地址”(Apple 的私密电子邮件中转服务)来创建一个唯一的随机电子邮件地址,并借用这个地址将邮件转发到您的个人电子邮件地址。这样一来,您不用共享自己的个人电子邮件地址,就可以收到由 App 发送的有用邮件。
    • 在使用您的 App 和网站时,“通过 Apple 登录”功能既不会跟踪您,也不会分析您的特征。Apple 只会保留必要的信息,以确保您能够登录和管理自己的帐户。
    • “通过 Apple 登录”功能内建了具有双重认证的安全保护机制。如果您在使用 Apple 设备,则可以随时通过面容 ID 或触控 ID 进行登录和重新认证。

除了"隐私和安全性",还有便利性等优点,不展开说了。

怎么用Sign in with Apple

参考官方资料 https://support.apple.com/en-us/HT211687

在 iPhone、iPad、iPod touch 或 Mac 上使用 “通过 Apple 登录” 功能创建帐户

在参加计划的 App 中或网站上,轻点“通过 Apple 登录”按钮。

比如“微博海外版”app的登录:

如果 App 或网站要求您提供姓名和电子邮件地址,“通过 Apple 登录”功能会自动填写您 Apple ID 中的信息。如果您愿意,可以编辑自己的姓名,然后选取“共享我的电子邮件”或“隐藏邮件地址”。

轻点“继续”,然后通过面容 ID、触控 ID 或设备密码确认登录。

每当您需要登录相应 App 或网站时,只需轻点 “通过 Apple 登录” 按钮,然后通过面容 ID、触控 ID 或设备密码进行确认即可。

在您登录了同一 Apple ID 的其他 Apple 设备上,操作方法是一样的。

哪些APP支持Sign in with Apple

Adobe,TikTok,Dropbox,Spotify,Airbnb等。

漏洞简介

参考 https://bhavukjain.com/blog/2020/05/30/zeroday-signin-with-apple/

2020年4月份,Bhavuk Jain (https://twitter.com/bhavukjain1) 发现了Sign in with Apple的一个0day漏洞。

对于此漏洞,Apple根据Apple Security Bounty计划向Bhavuk Jain支付了100,000美元。

该漏洞的危害:任意登录第三方APP。

具体说就是,攻击者只需要知道(可枚举)任意一个Apple ID的邮箱地址,就可以用这个Apple ID的身份,登录、接管这个Apple ID在第三方APP上的用户帐户。

工作原理

Sign in with Apple的工作原理与OAuth 2.0类似。

  • 第三方APP对用户的身份进行"身份验证"(authenticate)只有这2种方法:
    • 认证方法1 使用Apple服务器生成的一个JWT (JSON Web Token)
    • 认证方法2 使用Apple服务器生成的一段代码,这段代码的作用是生成一个JWT。

下面这个逻辑图,说明了"Sign in with Apple"的工作逻辑,包括JWT的创建和验证(validation),共6步:

注意:图里的箭头是逻辑含义,并不代表HTTP请求与响应方向!

第1步(Authorization Request) 的作用: 个人理解是,如果你在这一步成功登录了你的Apple ID,那么Apple确定了你的身份,你是已注册的合法的苹果用户。这是第2步的基础。

第2步(Authorization Granted) 的作用:为你当前的Apple ID创建一个可以登录第三方APP(如微博海外版)的合法凭证,并把它返回给客户端。

拿着这个合法凭证,那么后续所有的步骤(逻辑图第3-6步)都能顺利完成,否则后续流程被打断。

第2步(Authorization Granted) 的具体过程:

  • 在第2步中,在授权(authorizing)时,Apple会向用户提供一个选项,可以选择是否与第三方APP共享Apple Email ID(Apple电子邮件ID):
    • 如果用户选择了不隐藏Email ID,那就使用Email ID。
    • 如果用户选择了隐藏Email ID,则Apple会生成它自己的特定于用户的Apple relay Email ID(Apple中转电子邮件ID)。

个人理解:对一个第三方APP来说,用户做这个选择只能做一次。
举个例子,用户第一次用"Sign in with Apple"登录微博海外版时(相当于创建账号), 如果用户选择"隐藏Email ID"(使用Apple的“私密电子邮件中转服务”生成的地址), 那么用户以后用"Sign in with Apple"登录微博海外版时, 都会直接使用之前Apple为这个用户生成的“私密电子邮件中转服务”的地址。

根据用户选择,如果第2步顺利完成(成功授权),即: Apple服务器将为这个用户创建1个凭证,这个凭证包含了具有 Email ID(或Apple relay Email ID) 的JWT,并将这个凭证返回给客户端。

一个JWT,分为3部分,其中的payload,经过解码后如下所示:

{
  "iss": "https://appleid.apple.com",
  "aud": "com.XXXX.weblogin",
  "exp": 158XXXXXXX,
  "iat": 158XXXXXXX,
  "sub": "XXXX.XXXXX.XXXX",
  "c_hash": "FJXwx9EHQqXXXXXXXX",
  "email": "contact@bhavukjain.com", // 用户个人邮件地址. // or "XXXXX@privaterelay.appleid.com" Apple的“私密电子邮件中转服务”生成的地址
  "email_verified": "true",
  "auth_time": 158XXXXXXX,
  "nonce_supported": true
}

之后客户端就用这个合法凭证,完成后续所有的步骤(逻辑图第3-6步)。

漏洞分析

漏洞具体出在逻辑图里的哪一步? 第2步(Authorization Granted)。

Bhavuk Jain发现,登录Apple ID之后(完成里第1步),可以向Apple服务器发一个HTTP request(将其中的JWT中的Email ID改成任意的一个Email ID), 使用Apple的公钥验证了这些token的签名之后,这些token就显示为有效的。

从结果来看:
攻击者可以用任意一个Email ID获取到对应的合法凭证(JWT),然后顺理成章获得这个账户的访问权。

从具体过程来看:
第2步(Authorization Granted) 中发出的HTTP请求是这样的,只有一个参数email,没有任何其他参数!

( 在2020.11.5我专门抓包看了修复漏洞后的这个HTTP请求, 加入了其他参数, 如nonce 和 encryptedToken )

Sample Request (2nd step):

POST /XXXX/XXXX HTTP/1.1
Host: appleid.apple.com

{"email":"contact@bhavukjain.com"}

传递任意一个email, Apple就为这个特定的Email ID生成了一个有效的JWT (id_token)!! 并返回给客户端。这个逻辑显然是有问题的。

Sample Response Body:

{
  "authorization" : {
    "id_token" : "eyJraWQiOiJlWGF1bm1MIiwiYWxnIjoiUlMyNTYifQ.XXXXX.XXXXX",
    "grant_code" : "XXX.0.nzr.XXXX",
    "scope" : [ "name", "email" ]
  },
  "authorizedData" : {
    "userId" : "XX6位数字XX.XX32位小写字母数字混合XX.X4位数字X"
  },
  "consentRequired" : false
}

这个漏洞的影响非常严重,因为它能实现完全的"帐户接管"(account takeover)。

许多开发人员已经集成了"Sign in with Apple", 因为对于支持了"其他社交登录"(other social logins)的APP来说这是强制性的。
如“微博海外版”app,支持了qq登录,也要支持"Sign in with Apple"。

支持"Sign in with Apple"的APP有:Adobe,TikTok,Dropbox,Spotify,Airbnb等。

这些APP理论上都受影响。但实际上没做测试(不确定是否受影响),如果这些APP在验证用户时未采取任何其他的安全措施进行验证, 那么很容易对这些APP实现"帐户接管"(account takeover)。

Apple还对他们的日志进行了调查,并确定没有由于此漏洞引起的滥用或"帐户泄露"(account compromise)。

非常感谢Apple Security Team.

修复方案

修复方案: 根据标准授权协议,充分校验来自客户端的数据。

具体来看下Apple的修复结果,逻辑图整体不变,改了逻辑图里第2步(Authorization Granted)的具体的HTTP请求、响应。

(仅供参考,非真实数据)

具体的 HTTP request:

POST /appleauth/auth/oauth/authorize HTTP/1.1
Host: appleid.apple.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:80.0) Gecko/20100101 Firefox/80.0
Accept: application/json
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: https://appleid.apple.com/auth/authorize?client_id=notion.signin&nonce=493758775e30f12a539b31bbad9d397792f725c55be255b3&redirect_uri=https%3A%2F%2Fwww.notion.so%2Fapplepopupcallback&response_type=code&response_mode=form_post&scope=name%20email&state=eyJjYWxsYmFja1R5cGUiOiJyZWRpcmVjdCIsImVuY3J5cHRlZFRva2VuIjoiYmU3MTg3M2JiZGY2ZmU1YjMwMTUwZWJjMmYyNmJmNGFhYTdhNzg0MDE5NDYxOGEyMGQyMTc4OWZhODg3ZGQxOTBjMDI0NzcwNGZlYTJmYmY4ZDU2NzMzYTZkZGVlNDAzNWEyZmE4YTQyOGM3MDkzN2RmYzhlZDVjMWEwZjMzN2FmNGYwMGE5MTczZWNmMDBjYTFkMmIxZmM1YTI2IiwiZW5jcnlwdGVkTm9uY2UiOiI3MTJjODYzMDk4OWYwZTVjOWI4MmVjN2U4MzhkN2MyNDJkOThiMTdjMjI1MjE5NzY5NWFlOTY3NDRiNzFjMTVjOTMxNzAyNDUxZjQ3YzBiYjA4ZGRmMDEzOTRhNjNmOTcxODllNWFjNDdlOWM0MTQyYzk4NTNiMjg3ZWJhNTk0OGY2OWE0ZDNhMjdiOTNmMGI4NGQ4YjE2ZGRmNGMwMThlNDQ0ZDY2MTQyZmYzY2Y0MTcwMmYifQ%3D%3D
Content-Type: application/json
X-Apple-Widget-Key: 91f19b472c5c9be6ab17f3ec2b1b2b7db4d00a9a8c973e3d6c90dac08b91de71
X-Apple-I-FD-Client-Info: {"U":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:80.0) Gecko/20100101 Firefox/80.0","L":"zh-CN","Z":"GMT+08:00","V":"1.1","F":"V0a44j0e3NlY5BNlY5BSmHACVZXnN9138YHWuaWu_jpidPNs0ojpVMZ90L5H6fqUdHz13NldjV2pNk0ug9WK1RJdljf.j7J0gBZEKIxFMsI25BNlY5cklY5BqNAE.lTjV.EtU"}
X-Apple-ID-Session-Id: AEBE33C39E87473DED6397B311464C01
X-Apple-Auth-Attributes: L+TPt8FC4/GermNvQUQlWHUy01Z0ZVoWZ3V64ZkKi4A5MZXsjeged1aJH/UkUvari7Wau8/G631TwjLDTmAcDFR9PKcVqa0I1ppuAATIdRm9J94=
X-Apple-Privacy-Consent: true
X-Apple-Frame-Id: oauth-de322f88-6373-49d8-8a5f-d4474c09b1cc
X-Apple-OAuth-Client-Id: notion.signin
X-Apple-OAuth-Scopes: name email
X-Apple-OAuth-State: eyJjYWxsYmFja1R5cGUiOiJyZWRpcmVjdCIsImVuY3J5cHRlZFRva2VuIjoiYmU3MTg3M2JiZGY2ZmU1YjMwMTUwZWJjMmYyNmJmNGFhYTdhNzg0MDE5NDYxOGEyMGQyMTc4OWZhODg3ZGQxOTBjMDI0NzcwNGZlYTJmYmY4ZDU2NzMzYTZkZGVlNDAzNWEyZmE4YTQyOGM3MDkzN2RmYzhlZDVjMWEwZjMzN2FmNGYwMGE5MTczZWNmMDBjYTFkMmIxZmM1YTI2IiwiZW5jcnlwdGVkTm9uY2UiOiI3MTJjODYzMDk4OWYwZTVjOWI4MmVjN2U4MzhkN2MyNDJkOThiMTdjMjI1MjE5NzY5NWFlOTY3NDRiNzFjMTVjOTMxNzAyNDUxZjQ3YzBiYjA4ZGRmMDEzOTRhNjNmOTcxODllNWFjNDdlOWM0MTQyYzk4NTNiMjg3ZWJhNTk0OGY2OWE0ZDNhMjdiOTNmMGI4NGQ4YjE2ZGRmNGMwMThlNDQ0ZDY2MTQyZmYzY2Y0MTcwMmYifQ%3D%3D
X-Apple-OAuth-Redirect-URI: https://www.notion.so/applepopupcallback
X-Apple-OAuth-Response-Type: code
X-Apple-OAuth-Response-Mode: form_post
X-Apple-OAuth-Client-Type: thirdPartyAuth
X-Apple-OAuth-Require-Grant-Code: true
scnt: 1d42126e94a604b793442c68de1f3924
X-Requested-With: XMLHttpRequest
Content-Length: 814
Origin: https://appleid.apple.com
Connection: close
Cookie: dslang=CN-ZH; site=CHN; geo=CN; ccl=L/S0jx8GuOf+hFcV/16v/Q==

{"client":{"id":"notion.signin","redirectUri":"https://www.notion.so/applepopupcallback"},"scopes":[],"state":"eyJjYWxsYmFja1R5cGUiOiJyZWRpcmVjdCIsImVuY3J5cHRlZFRva2VuIjoiYmU3MTg3M2JiZGY2ZmU1YjMwMTUwZWJjMmYyNmJmNGFhYTdhNzg0MDE5NDYxOGEyMGQyMTc4OWZhODg3ZGQxOTBjMDI0NzcwNGZlYTJmYmY4ZDU2NzMzYTZkZGVlNDAzNWEyZmE4YTQyOGM3MDkzN2RmYzhlZDVjMWEwZjMzN2FmNGYwMGE5MTczZWNmMDBjYTFkMmIxZmM1YTI2IiwiZW5jcnlwdGVkTm9uY2UiOiI3MTJjODYzMDk4OWYwZTVjOWI4MmVjN2U4MzhkN2MyNDJkOThiMTdjMjI1MjE5NzY5NWFlOTY3NDRiNzFjMTVjOTMxNzAyNDUxZjQ3YzBiYjA4ZGRmMDEzOTRhNjNmOTcxODllNWFjNDdlOWM0MTQyYzk4NTNiMjg3ZWJhNTk0OGY2OWE0ZDNhMjdiOTNmMGI4NGQ4YjE2ZGRmNGMwMThlNDQ0ZDY2MTQyZmYzY2Y0MTcwMmYifQ==","anonymousEmail":true,"nonce":"493758775e30f12a539b31bbad9d397792f725c55be255b3","responseMode":"form_post","responseType":"code","email":"yourmail1@icloud.com"}

第2步(Authorization Granted) 具体的 HTTP response:

HTTP/1.1 200 
Server: Apple
Date: Thu, 05 Nov 2020 06:24:53 GMT
Content-Type: application/json;charset=UTF-8
Connection: close
X-Apple-I-Request-ID: 4b52ead3-4459-4ef1-bc55-d2cfe8344792
X-FRAME-OPTIONS: DENY
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Content-Security-Policy: default-src 'self'; script-src 'self' https://*.apple.com https://*.cdn-apple.com ; object-src 'self' https://*.apple-mapkit.com; style-src 'unsafe-inline' https://*.apple.com https://*.cdn-apple.com https://*.apple-mapkit.com ; img-src 'self' data: https://*.apple.com https://*.cdn-apple.com https://*.icloud.com https://*.mzstatic.com https://*.apple-mapkit.com ; media-src * data:; connect-src 'self' https://*.apple-mapkit.com; font-src 'self' https://*.apple.com https://*.cdn-apple.com; frame-src https://appleid.apple.com;
X-BuildVersion: R1-5
scnt: 6edb7d02cfaa17c57f5081897e32fdc9
Set-Cookie: dslang=CN-ZH; Domain=apple.com; Path=/; Secure; HttpOnly
Set-Cookie: site=CHN; Domain=apple.com; Path=/; Secure; HttpOnly
Pragma: no-cache
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Cache-Control: no-cache
Cache-Control: no-store
Set-Cookie: aa=C6F5614A911D51D95F5F191DFD3AB310; Domain=idmsa.apple.com; Path=/; Secure; HttpOnly
vary: accept-encoding
Host: appleid.apple.com
Content-Length: 386

{
  "authorization" : {
    "grant_code" : "cf792423ba34f1534bdd22665956c5f70.0.rxts.i0EII7mMKbmFh5rW3Lihot",
    "scope" : [ "name", "email" ]
  },
  "authorizedData" : {
    "anonymousEmail" : "qjwaptyrzp@privaterelay.appleid.com",
    "userId" : "000231.136da21fd4294323b784ac93afb3e261.0643"
  },
  "consentRequired" : false,
  "enableSignInWithAppleNewFirstTimeRunScreen" : false
}

总结

Apple这个授权过程存在的逻辑漏洞再次证明了一个道理:
即使标准协议本身的安全性较高,但是研发人员根据标准协议做实现时如果不够严谨的话,可能引发严重的安全问题。

点击收藏 | 0 关注 | 1
登录 后跟帖