Google が Facebook からメールアドレスを取り出すひとつの方法

  • Facebookが、ユーザのGmailの連絡先に入っているメールアドレスを使ってFacebook内の友人検索を実現している割には、Facebook自身は友人のメールアドレスを取り出すためのAPIを用意してない
    • Googleが、Facebookに対してGmailの連絡先にアクセスするためのAPIの使用を禁止した
      • Facebookが、APIを使わずにメールアドレスをインポートする機能をリリースした
        • うんぬん
  • Googleとしては、Facebookに友人のメールアドレスを取得する手段を提供させたいわけで

    • ん、公式アプリはどこから友人のメールアドレスとってるの?
    • というわけで、このアプリのSSL通信を調べてみました
  • *.facebook.com へのリクエストをproxyへ誘導するDNSサーバ
    • 普通にBINDを立てました
    • やっつけzoneファイル
 @         IN SOA   facebook.com. fakebook.facebook.com. (
                         2010022600    ; serial
                         3H            ; refresh
                         15M           ; retry
                         1W            ; expiry
                         1H )          ; minimum
 
           IN NS    facebook.com.

 @         IN A     192.0.2.1
 *         IN A     192.0.2.1
# setprop net.dns1 192.0.2.2
  • さて、アプリのデータをクリアして、ようやく起動です


  • ログインの通信はどうなっているかというと
https://api.facebook.com/restserver.php?
api_key=882a8490361da98702bf97a021ddc14d&
email=asannou%40gmail.com&
format=JSON&
method=auth.login&
migrations_override=%7B%27empty_json%27%3A+true%7D&
password=***&
sig=2b4b2d40c6c39695b43394f4a580d49e&
v=1.0
HTTP/1.1 200 OK
Cache-Control: private, no-cache, no-store, must-revalidate
Date: Sat, 26 Feb 2011 10:05:32 GMT
Pragma: no-cache
Content-Length: 205
Content-Type: application/json
Expires: Sat, 01 Jan 2000 00:00:00 GMT
Client-Date: Sat, 26 Feb 2011 10:05:30 GMT
Client-Peer: 66.220.147.25:443
Client-Response-Num: 1
Client-SSL-Cert-Issuer: /C=US/O=Equifax/OU=Equifax Secure Certificate Authority
Client-SSL-Cert-Subject: /C=US/O=api.facebook.com/OU=GT21570628/OU=See www.geotrust.com/resources/cps (c)09/OU=Domain Control Validated - QuickSSL Premium(R)/CN=api.facebook.com
Client-SSL-Cipher: RC4-MD5
Client-SSL-Warning: Peer certificate not verified
P3P: CP="Facebook does not have a P3P policy. Learn why here: http://fb.me/p3p"
Set-Cookie: datr=bNBoTVFSfZExPmusxqvADrTm; expires=Mon, 25-Feb-2013 10:05:32 GMT; path=/; domain=.facebook.com; httponly
X-Cnection: close
X-FB-Server: 10.36.40.110
X-Powered-By: HPHP

{"session_key":"***","uid":563587257,"secret":"***","access_token":"***"}
  • 本題のメールアドレス取得のところは
https://api-read.facebook.com/restserver.php?
api_key=882a8490361da98702bf97a021ddc14d&
call_id=1298747178987&
format=JSON&
method=fql.multiquery&
migrations_override=%7B%27empty_json%27%3A+true%7D&
queries=%7B%22user%22%3A%22SELECT+uid%2Cbirthday%2Cprofile_blurb%2Ccontact_email%2Cinterests%2Cmovies%2Csignificant_other_id%2Crelationship_status%2Creligion%2Cfirst_name%2Cabout_me%2Cname%2Cactivities%2Cpic_square%2Caffiliations%2Cmusic%2Cbooks%2Cprofile_url%2Cpolitical%2Ccell%2Cpic%2Ccurrent_location%2Chometown_location%2Cquotes%2Ctv%2Clast_name%2Cother_phone+FROM+user+WHERE+uid+IN%28100001821300493%29%22%2C%22significant_other%22%3A%22SELECT+last_name%2Cuid%2Cfirst_name%2Cpic_square%2Cname+FROM+user+WHERE+uid+IN+%28SELECT+significant_other_id+FROM+%23user%29%22%2C%22arefriends%22%3A%22SELECT+uid1%2C+uid2+FROM+friend+WHERE+uid1%3D563587257+AND+uid2%3D100001821300493%22%7D&
session_key=***&
sig=34ad94e3119978b130e0198eb6ba984f&
v=1.0
HTTP/1.1 200 OK
...

[{"name":"arefriends","fql_result_set":[{"uid1":"563587257","uid2":"100001821300493"}]},{"name":"user","fql_result_set":[{"uid":100001821300493,"birthday":"January 1, 1990","profile_blurb":"","contact_email":"asannou\u0040yahoo.co.jp","interests":"","movies":"","significant_other_id":null,"relationship_status":"","religion":"","first_name":"Nashiko","about_me":"","name":"Nashiko Zangyo","activities":"","pic_square":"https:\/\/s-static.ak.facebook.com\/rsrc.php\/v1\/y9\/r\/IB7NOFmPw2a.gif","affiliations":,"music":"","books":"","profile_url":"http:\/\/www.facebook.com\/profile.php?id=100001821300493","political":"","cell":null,"pic":"https:\/\/s-static.ak.facebook.com\/rsrc.php\/v1\/yV\/r\/Xc3RyXFFu-2.jpg","current_location":null,"hometown_location":null,"quotes":"","tv":"","last_name":"Zangyo","other_phone":null}]},"name":"significant_other","fql_result_set":}]
SELECT uid,name,contact_email FROM user WHERE uid IN(100001821300493)
[
  {
    "uid": 100001821300493,
    "name": "Nashiko Zangyo",
    "contact_email": null
  }
]
    • contact_email が null になる!
    • さらに、ログインのレスポンスに含まれていた access_token を使うと
https://api.facebook.com/method/fql.query?
query=SELECT+uid,name,contact_email+FROM+user+WHERE+uid+IN(100001821300493)&
access_token=***&
format=json
[{"uid":100001821300493,"name":"Nashiko Zangyo","contact_email":"asannou\u0040yahoo.co.jp"}]
    • やっぱり contact_email が取れる!
  • 以上のことから、FacebookAPIapi_key によってメールアドレスの扱いを変えていることがうかがえます
    • 実際に利用しようとしたときに問題となるのは sig パラメータ(署名)ですが、Androidアプリであるためリバースエンジニアリング秘密鍵を取り出すのは難しくないと思います
    • また、OAuth 2.0では署名がなくなっているので、もし公式アプリが移行するようなことがあれば、それすら不要ですね
      • そういう意味では、2.0は1.0より秘密鍵を守れなくなっている
        • 個人的には、そもそもクライアントアプリの秘密鍵イラネ派ですが
  • ポリシーを守りたいのなら、公式アプリに特別なパワーを与えるのは危ないんじゃねという話でした