** 本記事は、Slack admits to leaking hashed passwords for five yearsル の翻訳です。最新の情報は英語記事をご覧ください。**
人気のコラボレーションツール Slack が、同社のデータ管理に長期にわたって欠陥があったことを認めました
(注 : Linux ディストリビューションの Slackware とは異なります) 。
この件に関して、同社は「Slack のパスワードリセットについて」と題した声明を発表しました。同声明で同社は、「ユーザーがワークスペースの共有招待リンクを作成または取り消す際に、誤って個人データを必要以上に共有していた」と認めました。
同社によれば、2017 年 4 月 17 日から 2022 年 7 月 17 日までに送信された招待リンクには送信者のハッシュ化されたパスワードデータが含まれていたそうです (4 月 17 日と 7 月 17 日を含むものと思われる) 。
問題の本質
この侵害の本質について、Slack のセキュリティアドバイザリは明確な説明を発表していません。唯一以下のような説明がなされただけです。「このハッシュ化されたパスワードは Slack クライアントからは見えないため、このバグを発見するためには Slack のサーバーから送られてくる暗号化されたネットワークトラフィックを詳細に監視する必要がありました」
つまり、パスワード情報は送信されたネットワークパケットに含まれていたものの、意図的に表示されることはなかったため、ほとんどの受信者は受信データにハッシュ化されたパスワード情報が含まれていることに気づかなかったと思われます。また、データは TLS 接続で送信され、接続先に到達するまで復号化されないため、攻撃者が途中でそれに気づくことはなかったと考えられます。
これは不幸中の幸いといえます。とは言え、大きなリスクであることに違いはありません。
受信者が通常使用したり目にしたりすることのないデータがネットワークパケットには含まれていることはよくあります。
典型的な例として、HTTP ヘッダが挙げられます。HTTP ヘッダはブラウザへの指示であり、閲覧している Web ページに表示するためのデータではありません。
また、ユーザーには無関係なデータや目に見えないデータもログに残ってしまうことがよくあり、特にファイアウォールのログは永久に保存されるおそれがあります。
ソルト化、ハッシュ化、ストレッチング
<pSlack の発表によれば、流出したデータは単にハッシュ化だけでなく、ソルト化もされていたことがわかりました。つまり、ハッシュ関数を適用する前の各ユーザーのパスワードには、そのユーザーに固有のランダムなデータが付与されていたということです。
ハッシュ関数とは、基本的に不可逆的な関数です。そのため、左から右の方向へ計算するのは容易ですが、逆算は容易ではありません。
たとえば、以下の計算は容易に行うことができます。
SHA256("DUCK") = 7FB376..DEAD4B3AF008
しかし、逆に 7FB376..DEAD4B3AF008
という値から DUCK
K を割り出すのは容易ではなく、辞書にある全ての単語を一つずつ試行して合致する値を見つけるしかありません。
SHA256("AARDVARK") = 5A9394..467731D0526A [X] SHA256("AARON") = C4DDDE..12E4CFE7B4FD [X] SHA256("ABACUS") = BEDDD8..1FE4DE25AAD7 [X] . . . 3400 skipped SHA256("BABBLE") = 70E837..CEAD4B1FA777 [X] SHA256("BADGER") = 946D0D..7B3073C1C094 [X] SHA256("BAGPIPE") = 359DBE..BE193FCCB111 [X] . . . 3200 skipped SHA256("CABAL") = D78CF4..85BE02967565 [X] SHA256("CACHE") = C118F9..22F3269E7B32 [X] SHA256("CAGOULE") = 5EA530..5A26C5B56DCF [X] . . . 5400 skipped SHA256("DAB") = BBCC8E..E8B98CAB5128 [X] SHA256("DAFFODIL") = 75121D..D6401AB24A98 [X] SHA256("DANGER") = 0BD727..4C86037BB065 [X] . . . 3500 skipped SHA256("DUCK") = 7FB376..DEAD4B3AF008 [FOUND!]
また、ユーザーごとに異なるソルト ( ソルトは秘密鍵を使用する必要はありません ) を設定することで、たとえ 2 人のユーザーが同じパスワードを選択したとしても、同じパスワードハッシュが生成されないようにすることができます。
以下の図を見ると、ソルト化の効果がよくわかります。DUCK
という単語を 3 つの異なるプレフィックスでハッシュ化すると、全く異なったハッシュ値が生成されます。
SHA256("RANDOM1-DUCK") = E355DB..349E669BB9A2 SHA256("RANDOM2-DUCK") = 13D538..FEA0DC6DBB5C <-- Changing just one input byte produces a wildly different hash SHA256("ARXXQ3H-DUCK") = 52AD92..544208A19449
また、ソルト化によって、攻撃者が使用されている可能性の高いハッシュ関数を事前にまとめたリストを製作したり、照合を速めるためにハッシュ関数をまとめた表 (レインボーテーブル) を作成したりするのを防ぐことができます (存在する可能性のあるソルトごとに、まったく新しいハッシュリストやレインボーテーブルが必要になるからです)。
つまり、ほとんどの場合ハッシュ化とソルト化されたパスワードからは平文は割り出せないのです。元のパスワードが複雑でランダムに選ばれている場合はなおさら割り出すのが困難になります。
Slack は、ストレッチングについては言及していません。今回の声明において、パスワードのハッシュに対してストレッチングを実施したのか、実施したのであればどのように行ったのかについては一切述べられていません。
ストレッチングとは、攻撃者の既知のパスワードハッシュに対する辞書攻撃にかかる時間を増大させるために、パスワードのハッシュ化を数万回単位で繰り返し行うことです。
仮に、攻撃者が既知のハッシュを用いてハッシュ化とソルト化されたパスワードへの辞書攻撃を毎秒 10 万単語分行うとすると、攻撃者は毎分 600 万個、3 時間で 10 億個以上の異なる辞書単語とその派生語を用いてログインを試行できることになります。
一方、ストレッチングを行うと、攻撃者が 1 時間に試行できる辞書攻撃の回数は 3600 回にまで低下します。余程簡単なパスワード以外は、どんなに時間をかけても推測される恐れはほとんどありません。
ストレッチングのための計算に 1 秒掛かった結果として、ログインに 1 秒余計に時間が掛かったしても、ユーザーにはほとんど実害はないでしょう。
ソルトとハッシュ、ストレッチングのためのアルゴリズムとして、PBKDF2
、bcrypt
、scrypt
、Argon2
などがよく知られています。これらのアルゴリズムを用いれば、攻撃者のパスワード推測に要する時間を長くすることができ、いわゆる辞書攻撃や総当り攻撃の可能性を減らすことができます。
辞書攻撃とは、パスワードに用いられる可能性のある単語を用いてログインを試行する攻撃方法です。候補となる単語のあまりの多さに、攻撃はほとんどいつも失敗に終わります。総当たり攻撃とは、AAA..AAAA
から ZZZ..ZZZZ
まで ( 16 進数のバイト単位で考えれば、0000..000000
から FFFF..FFFFFF
までが候補となる ) の、意味を全くなさない文字列までを含めたあらゆる文字列候補を試行する攻撃方法です。
対策
Slack の発表によれば、約 200 人に 1 人のユーザーが被害を受けています (これは全体の 0.5% にあたります。この数字は、パスワードデータが流出していた期間に生成された共有招待リンク数の記録に基づくと思われます)。同社は、被害を受けたユーザーにパスワードをリセットするように強く求めていくとしています。
Slack のユーザーは他にも以下のような措置を講じてください。
- Slack のユーザーであれば、同社からパスワードの再設定を求められたかどうかに関わらず、パスワードを再設定した方がよいでしょう。 一般的に、ハッシュを流出させるなどのパスワードデータ管理上の不手際を企業が認めた場合、自分のパスワードも影響を受けていると考えましょう。特に今回ほど長期にわたって流出していた場合は、企業が影響を認めていなかったとしてもパスワードを再設定すべきです。パスワードを変更すると同時に、古いハッシュは攻撃者にとっての使用価値がなくなります。
- 現在パスワードマネージャーを使っていない場合は導入を検討してください。 パスワードマネージャーは、 適切なパスワードを設定する際に便利です。パスワードマネージャーを使用してパスワードを設定すると、今回のような事件でパスワードを割り出されるリスクをかなり下げることができます。総当たり攻撃を行う際、攻撃者は、単語や、単語と数字の組み合わせなどの使用されている可能性の高いパスワードを最初に試し、攻撃が進むにつれてより長く複雑なパスワードへ移行していきます。なぜなら、試行するパスワードの数があまりにも多すぎるため、純粋な意味での総当たり攻撃は実行不可能だからです。パスワードマネージャーを用いれば、20 文字程度のランダムなパスワードを簡単に記録しておくことができます。
- 能であれば 2FA ( 二要素認証 ) を有効にしてください。2FA (二要素認証) とは、ログインにパスワードだけでなく、毎回変わるワンタイムコードを要求するセキュリティ機能です。このコードは通常、携帯電話に送信 ( または携帯電話で生成 ) され、有効期間はわずか数分間です。つまり、たとえパスワードが解読されたとしても、それだけでは攻撃者はアカウントを乗っ取ることはできません。
- パスワードを扱う際には、信頼できるソルト化、ハッシュ化、ストレッチング用アルゴリズムを使用してください。万が一、パスワードデータベースが侵害された場合でも、信頼できるアルゴリズムを使用していればアルゴリズムとセキュリティ設定の詳細を顧客に正確に伝えることができます。ユーザーは、詳細な情報を基にして盗まれたハッシュがその時点までに解読された可能性がどの程度あるのかを自分で判断できるようになります。