現在、Twitter APIのエンドポイントにはSSL 接続のみが許可されています。 SSL 上でやり取りをすれば、ユーザーとTwitter API間の公開インターネット上での情報を保護することにより ユーザーのプライバシーを確保することができます。
OAuth ではユーザーの資格情報の代わりにOAuthトークンを使用することで、通信時にユーザーのパスワードが抜かれることを防いでいますが、それだけでは完全なプライバシーの確保には十分ではありません。
Twitterのサーバとあなたのクライアントは、コネクション上でcipher specをネゴシエートします。 可能であれば、Twitter がセッション暗号化に使っている既定のcipher (現在は RC4)を使うのが良いでしょう。 While other ciphers may offer better performance or security (and may be supported by both your client and Twitter’s servers,) the preferred cipher as negotiated by our servers is typically the best available for communication. あなたのプログラム上でネゴシエート選択の処理を上書きすることは推奨されません。
api.twitter.comで使われているTwitterSSL証明書はベリサイン社によって署名されています。 si0.twimg.com上にある(si4.twimg.comを経由する)ようなコンテンツについて、 それらの証明書は Verisign か Contendo 、もしくはその両方によって署名され、どれが使われるかは地理的に最も近い CDN サーバに依存します。
あなたのアプリケーションでは、全てのTwitter サーバへ返される証明書チェーンがTwitter が承認するベンダー(twitter.comならVerisign EV、api.twitter.comならSymantec 、それ以外はDigicert )によって署名され、それ以外のCAルートになっていないかを確認しなければなりません。
これを書いている時点で、 api.twitter.comの証明書は以下のとおりです:
Certificate: Data: Version: 3 Serial Number: 7f:cd:88:a8:2d:77:bf:6e:11:b9:91:4d:ac:7c:b8:d3 Signature Algorithm: SHA256withRSA Issuer: C=US/O=Symantec Corporation/OU=Symantec Trust Network/CN=Symantec Class 3 Secure Server CA - G4 Validity Not Before: 2014-Jul-22 00:00:00 GMT Not After: 2018-Oct-09 23:59:59 GMT Subject: C=US/ST=California/L=San Francisco/O=Twitter, Inc./OU=Twitter Security/CN=api.twitter.com
これを書いている時点で、 api.twitter.com はシリアルのSymantec Class 3 Secure Server CA - G4ルート証明書で署名されています: 51:3f:b9:74:38:70:b7:34:40:41:8d:30:93:06:99:ff. あなたのプログラムではこの Symantec “G4” ルート証明書を信頼済みとして扱ってください。
可能であれば、証明書の有効性を検証する場合は、ローカルのオペレーションシステムに依存した処理を行わないようにしてください。 マルウェアやローカルのITスタッフ、その他不正動作によって改竄することができるからです。 api.twitter.comへの接続には、上記に記載された有名なベンダーのみを有効にしてください。 Twitter の承認済み一覧に載っていないベンダーの証明書は、あなたのアプリケーションの信頼済みCAルートストアにインクルードしないでください。
Symantec社、Verisign社、Digicert社のルートCA証明書は全て、信頼済みCAファイルに追加することを強く推奨します。それらベンダーのうち一つが異なるルートを持つ新しいキーを署名した場合にも、あなたのアプリケーションは正常に動作を続けることができます。 SSLを介してコンテンツを取得している場合は、以下CDN の項目に一覧表記されたSSLルート証明書もインクルードする必要があります。
Digicert — https://www.digicert.com/digicert-root-certificates.htm
Verisign — https://www.verisign.com/support/roots.html
現在のUTCシステム時間と比較し、取得した証明書の “Not After”属性と “Not Before”属性を検証してください。 有効期限が切れていた場合(もしくは有効でなかった場合)は、警告を返すかユーザーリクエストへの応答を一切拒否するか、もしくはその両方を行ってください。 さらに、システム時間を外部の信頼できるタイムソースと比較して検証し、時間がズレている場合はユーザーに通知してください。 多くのユーザーは自分のシステム時間を正しく設定することを忘れています! SSL での検証は、ホストオペレーションシステムで正しい時間が設定されているかに大きく左右されます。
大抵のアプリケーションでは取得した証明書の失効リストは確認しておらず、確認するかどうかはOSに依存します。 あなたのアプリケーションやSSLライブラリでは、Twitterから証明書を受け取る前にCRL とOCSP (Online Certificate Status Protocol)の検証を行うよう設定されているか確認してください。
配信速度を向上させるため、Twitter における背景画像、アバター画像、JavaScript サービスは様々な CDN (Content Delivery Networks) によって提供されています。 画像を使用する際にはユーザーの接続に関する情報が漏れないように注意しなければなりません。例えば、APIとの接続がHTTPSを介して行われる場合、アバター画像もHTTPSで表示する必要があります。 サーバとのHTTPS接続処理を自身のコードで記述している場合は、TwitterのCDNルート全てのCA証明書もインクルードしなければなりません。 Alternately, rely on the host operating system or browser for these CA certificates.
You should never mix content in your application. If you mix content, an observer monitoring the network connection could assemble (through traffic analysis) a list of who your user is communicating with, violating the user’s privacy. HTTPSで接続を開始した場合は、その接続は常にHTTPSで行い続けるようにしてください。
メディアを含んだツイートを表示する場合、画像の表示にはmedia_url_https
属性のHTTPS URLを使用してください。
Twitterと通信をする際には、既に世に出回って十分にテストされているライブラリを使ってAPIと通信をするのがベストです。 サーバとやり取りする部分のコードを自分で記述しなければならない場合は、以下にメジャーなプログラム言語のコード例があるので、証明書の検証を完璧に行って適切にSSL接続をする助けになるでしょう。
CURL は、WebアプリケーションのテストとAPIとの通信によく使用されます。アプリケーションで libcurl を使用している場合は、受け入れるX509 ルート証明書の一覧であるCACert ファイルを用意する必要があります。
Twitter recommends that developers using TLS/SSL connections using libcurl verify that the CURLOPT_SSL_VERIFYPEER option is set to boolean value True (or integer value 1) and ensure that failure to return a successful verification results in a failed connection error rather than the establishment of an untrusted and unsecured connection. また、可能であればSSLの verifydepth をmaximum (9) に設定することを推奨します。
コマンドラインから、 capath (もしくは cafile)オプションを追加してVerisign ルートCA証明書を含むファイルをインクルードしてください:
curl -3 -capath --ssl https://api.twitter.com
curl_setopt($connection, CURLOPT_SSL_VERIFYPEER, True); curl_setopt($connection, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt($connection, CURLOPT_CAINFO, "path:/ca-bundle.crt");
require 'net/http' require 'net/https' require 'uri' RootCA = '/etc/ssl/certs' url = URI.parse 'https://api.twitter.com/yourrequestgoeshere' http = Net::HTTP.new(url.host, url.port) http.ca_path = RootCA http.verify_mode = OpenSSL::SSL::VERIFY_PEER http.verify_depth = 9 request = Net::HTTP::Get.new(url.path) # handle oauth here, or whatever you need to do... response = http.request(request) # ... process response ...
PythonのSSL検証についてはこのStack Overflow の投稿を参照してください。 Pythonのバージョンやあなたが使用しているライブラリによっては、ライブラリがこの検証手順を普通にサポートしているかもしれませんし、コネクションから証明書を抽出して自分で追加の検証手順を実行しなければならないかもしれません。
2014年2月26日から、 api.twitter.com はSSLでないトラフィックに対して 403 ステータスコードを返すようになりました。 あなたのクライアントのコードではこのエラーを制御できるようにしてください。
ユーザーへ常に詳細なエラーメッセージを返すことで、ユーザーはどの段階で接続失敗したのかを識別することができます。例えば、TCP接続でSSL証明書の検証に失敗した場合、 “接続には成功しましたがSSL証明書の検証に失敗しました(Connect succeeded, but SSL certificate verification failed.)”というメッセージ詳細を返せば直接問題を特定できます。 単に “接続失敗(Connection Failed)” とだけ表示されると、SSL関連の原因をデバッグするのがとても難しくなります。
大抵の場合、ユーザーはSSLの接続トラブルを直接Twitterのサポートへ報告します(そしてあなた方開発者へは報告しません)。 詳細なエラーメッセージが報告されれば、我々のチームは問題があなたのコードにあるのか(中間攻撃者など)、Twitter側にあるのか(証明書の失効やその他プロダクトの問題)を判別できます。 Twitter 社員はずっと自社のSSLインフラをモニタしているので、後者が原因であなたのアプリケーションに影響を与えることはめったにありません。 多くの場合、SSL接続エラーはクライアントのローカル環境のプロキシやネットワークインフラで何らかの変更が行われたことが原因です。適切なエラーメッセージを生成して制御することが、ユーザーの問題解決を助けるのです。
可能であれば、あなたのアプリケーションとTwitter間の現在の状態を表示するようにしてください。 ウェブブラウザによっては南京錠のアイコンを表示したり、現在の接続状態を詳細なメッセージで表示したりします。