2015年以来、私たちは世界中の開発者を対象に、セキュリティに対する積極的で前向きなアプローチを行っています。コードを保護するためのスキルを身につけてもらい、再作業や修正を減らし、セキュリティチームを楽しい警察以外のものとして見てもらえるように支援しています。
私たちは、開発者が銀河系中のコードを安全に保護するために、開発者のそばにいることを約束しています。しかし、そろそろ状況を変えて、戦場で鍛えられたセキュリティ意識の高い開発者を次のレベルに引き上げる時です。
この度、Secure Code Warrior プラットフォームの新機能として、Missions がリリースされました。この全く新しいチャレンジカテゴリーは、開発者によるセキュリティトレーニングの次の段階であり、ユーザーはセキュリティの知識を思い出すことから、実際のシミュレーション環境でそれを適用することになります。
最初にプレイできる公開ミッションは、GitHubのUnicode侵害のシミュレーションです。一見、単純そうに見えますが、実に巧妙な脆弱性であり、解剖するのが楽しいのです。セキュリティ研究者の0xsha氏は、この同じバグが大文字小文字の変換によってDjangoを悪用する方法について包括的なケーススタディを行い、同時に脆弱性の挙動がプログラミング言語によってどのように変化するかを明らかにしました。このセキュリティ問題については、まだまだ多くの発見がありますが、私たちのミッションはその出発点として最適なものです。
GitHubの真っ向勝負(ケースマッピング)の衝突
セキュリティ研究グループのWisdomは、2019年11月28日のブログ記事で、GitHubで発見したセキュリティバグについて報告しました。彼らは、UnicodeのCase Mapping Collisionを利用して、誤ったメールアドレス(攻撃者のように考えれば、脅威主体が選んだメールアドレス)へのパスワードリセットメール配信を引き起こすことができたことを概説しました。
セキュリティの脆弱性は決して良いニュースではありませんが、ホワイトハットのセキュリティ・リサーチャーは、コードベースの中に悪用可能なエラーを発見した場合には、救いの手を差し伸べてくれます(言うまでもありませんが)。彼らのブログやレポートはしばしば素晴らしい読み物となり、新しい脆弱性やその仕組みを知ることはとても素晴らしいことです。
セキュアコーディングの能力を次のレベルに引き上げるためには、一般的な脆弱性(特にクールな新しい脆弱性)を見つけるだけでなく、悪意のある脅威のアクターがこれらの新しい技術を使ってデータを掘り起こすための肥沃な土地を探していることを知っているので、非常に強力な力となります。
では、実際にやってみましょう。UnicodeのCase Mapping Collisionがどのように悪用されるのか、それがリアルタイムでどのように見えるのか、そして、セキュリティ・リサーチャーの心構えを持って、自分で試してみることができるのかをご紹介します。
今すぐCase Mapping Collisionに挑戦してみませんか?ステップアップしてください。
ユニコード。複雑で無限のカスタマイズが可能、そして絵文字だけではない
"ユニコード」という言葉は一般の人には馴染みがないかもしれませんが、ほとんどの人が毎日何らかの形で使っているはずです。WebブラウザやMicrosoftのソフトウェアを使ったことがある人、絵文字を送ったことがある人は、Unicodeを間近で見たことがあるはずです。これは、世界中のほとんどの文字体系のテキストを一貫してエンコードし、取り扱うための規格で、誰もが(デジタル上で)1つの文字セットを使って自分自身を表現できるようにするものです。現在、143,000以上の文字があるので、アイスランド語を使おうが、トルコ語のドットレスを使おうが、その中間の文字を使おうが、問題ありません。
Unicodeには非常に多くの文字が含まれているため、多くの場合、文字を別の「同等の」文字に変換する方法が必要になります。例えば、ドットレスのあるUnicode文字列をASCIIに変換すると、単純に「i」になるのは理にかなっていると思いませんか?
膨大な量の文字をエンコードすることは、大きな災害を引き起こす可能性があります。
Unicodeのケースマッピングの衝突は、ビジネスロジックの欠陥であり、その核心は、2FAで保護されていないアカウントの乗っ取りにつながる可能性があります。問題の脆弱性を説明するために、実際のコードスニペットでこのバグの例を見てみましょう。
app.post(/api/resetPassword, function (req, res) {
var email = req.body.email;
db.get(SELECT rowid AS id, email FROM users WHERE email = ?, [email.toUpperCase()],
(err, user) => {
if (err) {
console.error(err.message);
res.status(400).send();
} else {
generateTemporaryPassword((tempPassword) => {
accountRepository.resetPassword(user.id, tempPassword, () => {
messenger.sendPasswordResetEmail(email, tempPassword);
res.status(204).send();
});
});
}
});
});
論理的には次のようになります。
- ユーザーから提供されたメールアドレスを受け取り、一貫性を保つために大文字にします。
- メールアドレスがすでにデータベースに存在しているかどうかをチェックする
- もしそうであれば、新しい一時的なパスワードを設定します(ちなみに、これはベストプラクティスではありません。代わりに、パスワードリセットを可能にするトークンを含むリンクを使用してください。)
- そして、ステップ1で取得したアドレスに、一時的なパスワードを記載したメールを送信します(これは多くの理由から、非常に悪い習慣です。
オリジナルのブログ記事で提供されている例では、ユーザーが電子メール John@GıtHub.com (トルコ語のドットレスiに注意)のパスワードリセットを要求した場合に何が起こるかを見てみましょう。
- John@Gıthub.com を JOHN@GITHUB.COM に変換するロジックです。
- それをデータベースで調べて、ユーザー JOHN@GITHUB.COM を見つけます。
- 新しいパスワードを生成し、それを John@Gıthub.com に送信します。
なお、このプロセスでは、機密性の高いメールを誤ったメールアドレスに送信してしまいます。おっと!
このユニコードの悪魔を追い出すには
この特定の脆弱性の興味深い点は、脆弱性となる要因が複数あることです。
- 実際のUnicodeキャスト動作
- データベースに登録されているメールアドレスではなく、ユーザーから提供されたメールアドレスを使用することを決定するロジックです。
理論的には、Wisdomのブログ記事にあるように、この特定の問題を2つの方法で解決することができます。
- ピュニコード変換でメールをASCIIに変換する
- ユーザーが入力したメールアドレスではなく、データベースに登録されているメールアドレスを使用する
ソフトウェアを強化する際には、可能な限り多くの防御策を講じてチャンスを逃さないようにすることが大切です。このエンコーディングを悪用する別の方法があるかもしれませんが、それはまだ知られていません。リスクを減らし、攻撃者が開いている可能性のある窓を閉じるためにできることは何でもあります。
自分で試してみませんか?
ほとんどの開発者は、データの漏洩がビジネスに悪影響を及ぼすことを認識しています。しかし、セキュリティを意識したエンジニアは、増大する脆弱性、侵害、サイバーセキュリティの悩みに対する強力な解毒剤となります。
あなたの安全なコーディングと意識向上のスキルを次のレベルに引き上げる時が来ました。このGitHubの脆弱性を、フロントエンドとバックエンドの両方のコンテキストで、悪いコードの影響を見ることができる、没入型の安全なシミュレーションで体験しましょう。攻撃者は有利な立場にいるので、競技場を均等にして、ホワイトハットのカウンターパンチで本物のスキルを適用しましょう。