Unicodeで絶対知っておくべきセキュリティ5つの注意(翻訳)|TechRacho(テックラッチョ)〜エンジニアの「?」を「!」に〜|BPS株式会社エンジニアの「?」を「!」に。原著者の許諾を得て翻訳・公開いたします。多くの書籍を出版しています。FitNesse画像はすべて元記事からの引用です。Androidの偽アプリ出現」のニュースによると、公式アプリと同じ開発者に見える名前で偽アプリが提供されました。この詐欺師は、印刷に現れないスペース文字を開発者名に混ぜ込むことでバリデーションのすり抜けに成功しました。Storeのメンテナーが気づくまでに100万人以上が騙されました。Unicodeの標準としての価値は計り知れません。UnicodeのおかげでPCやスマホ、ウォッチを問わず同じメッセージを同じ方法で世界中どこでも表示できます。残念なことに、Unicodeの複雑さが原因となって、詐欺師やいたずら小僧どもにとって格好の金の鉱脈になってしまっています。Unicodeで引き起こされる基本的な問題をGoogleなどの巨大企業が食い止めることができなかったら、中小企業にとっては勝ち目のない戦いに感じられてしまうのではないでしょうか。問題を引き起こしているのは、ほとんどが一握りの乱用です。詐欺行為を防ぐために、開発者なら誰もが知っておくべきUnicodeの知識トップ5をご紹介いたします。画面に表示されないUnicodeポイントがたくさんあるUnicodeにはゼロ幅のコードポイントがいくつもあります。non-joiner(U+200C)はハイフネーションのヒントとして使われます。これらの文字は画面上には表示されませんが、文字列を比較するときに影響を与えます。WhatAppアプリの詐欺が長期間気づかれなかった理由はこれです。U+2000〜U+206F)に含まれています。一般に、IDの文字でこのブロックのコードポイントを利用する必然性はないので、最も簡単にフィルタできます。Separatorのように、この範囲外にも特殊な非表示コードがいくつか存在します。一般に、Unicodeの一意性制約に単純な文字列比較を使うのは危険です。考えられる回避法としては、悪用される可能性のあるIDやその他のデータに許可されている文字セットを制限することです。残念ながら、これですべての問題を解決できるわけではありません。見た目が極めて似ているコードポイントがたくさんあるUnicodeは世界中のあらゆる手書き言語で使われるシンボルをすべてカバーしようとしているため、人間には区別不可能なほど見た目が互いによく似ている文字がどうしても増えてしまいます。コンピュータならあっさりと区別できます。この問題を利用したいたずらとしてMimicというお遊びユーティリティがあり、これはソフトウェア開発でよく使われるシンボル(コロンやセミコロンなど)を見た目のよく似た別のUnicode文字に差し替えてしまいます。コード編集ツールはカオスと化し、開発者は混乱の中に取り残されてしまいます。見た目のよく似たシンボルの問題は、単なるいたずらにとどまりません。homomorphicという造語で呼ばれる、これを悪用した攻撃手法によって深刻なセキュリティ問題が生じることがあります。2017年4月、セキュリティの研究者は異なる文字セットを混ぜ込むことでapple.comと見た目のそっくりなドメインを登録し、さらにSSL証明書まで取得してみせました。主要なブラウザは何も知らずにSSL鍵を表示し、このドメインを「安全」なものとして扱ってしまいました。表示可能文字と非表示文字の混在と同様、ID(特にドメイン名)の文字に別の文字セット名の混用を許可する正当性はまずありません。ほとんどのブラウザでは、文字セットの混在したドメイン名を16進Unicode値で表示することでペナルティをかけ、ユーザーが簡単に惑わされないようにしています。ユーザーにIDを表示しようとする場合(検索結果など)は、混乱防止のため同様の手法を検討してください。これも完全な解決方法ではありません。sap.comやchase.comといった一部のドメインは、非ラテン文字セットのブロック1つだけで完全に構成できてしまいます。Unicodeコンソーシアムは紛らわしい文字一覧を公開しており、詐欺の可能性を自動チェックするときの資料として有用かもしれません。その他に、紛らわしい文字の簡単な作り方をお探しの方はShapecatcherというサイトをチェックしてみてください。このツールは、手書きの文字に似ているUnicodeシンボルのリストを表示します。正規化で正しく正規化されるとは限らないユーザー名などのIDで、ユーザーのID入力方法が異なる場合にも処理を統一するためには、正規化(normalization)が重要です。IDの正規化によく使われる方法のひとつは、すべて小文字に変換することです。JamesBondはjamesbondと同じになります。互いによく似た文字や重複したセットが多数存在するため、(自然)言語が異なっていたりUnicode処理ライブラリが異なっていたりすると、適用される正規化戦略もそれによって変わってしまうことがあります。正規化が複数箇所で行われていると、セキュリティ上のリスクにつながる可能性があります。要するに、アプリのさまざまな部分で行われる小文字変換の動作がすべて同じであると仮定すべきではないということです。Goldmann氏は、同社のユーザーのひとりがアカウントハイジャック手法を発見した後、この問題について2013年に見事なインシデント分析を行いました。攻撃者が他人のユーザー名をUnicode異体字で登録すると(BIGBIRDなど)、同じ正規アカウント名(bigbird)に変換される可能性があります。語の正規化手法がアプリのレイヤごとに異なる場合、偽アカウントを登録してパスワードをリセットできてしまいます。基本的なラテン文字や大半のヨーロッパ文字セットでは、画面や紙の上のあるテキスト片の占めるスペースは、シンボルの個数におおむね比例し、テキストのメモリ上のサイズにもおおむね比例します。EM(「M」という文字の幅)やEN(「N」という文字の幅)が長さの単位としてよく使われる理由はこれです。Unicodeで同じようなことを仮定するのは危険です。Ar-Raheem(U+FDFD)のように、たった1文字でそこらの英単語よりも長くなる愛すべきシンボルは山ほどあり、Webサイトで仮定される表示上の囲みからあっさりはみ出してしまいます。文字列の文字長をベースとするワードラップやテキスト折り返しのアルゴリズムはことごとく破綻してしまうということです。ターミナルで動作するCLIプログラムのほとんどは固定長フォントを前提としているので、ターミナルにこうした文字を表示すると、引用符の位置が完璧にずれてしまうのがわかります。generatorというサイトは、入力したテキスト片の周りにゴミ文字を大量に追加して、テキストが上下方向に大きくはみ出すように変えてしまいます。非表示コードポイント全体の問題によってメモリサイズと画面上のサイズの関連は失われてしまうので、画面サイズに収まるよう巧妙に調節したテキストをフィールドに入力すればデータベースのフィールドがパンクするかもしれません。固有のスペース(幅)を持たない例は他にも膨大にあるので、非表示文字をフィルタするだけでは不十分です。character」は直前の文字の上に配置されるので、1行のテキスト内に複数行のテキストを書くことができます(N\u036BO\u036CはNͫOͬと表示される)。ヘブライ語聖書の経典朗唱向けのイントネーションを表すカンティレーションマーク(参考)は、同じ表示スペースにいくつでも重ねられるので、画面上のたった1つの文字に大量の情報をエンコードするという悪用が簡単にできてしまいます。Kleppeは、古典的なライフゲーム(参考)のブラウザ版実装にカンティレーションマークをエンコードしてみせました。このページのソースコードを見た方は相当なショックを受けるでしょう。Unicodeは単なるパッシブデータではないコードポイントによっては、表示可能な文字の表示方法に影響を与えるよう設計されているものがあります。ユーザーがコピペしているのは単なるデータ以上のものであり、処理インストラクションも入力できるということです。override(U+202E)文字でテキストの進行方向を変えてしまうというのがあります。MapsでNinjasを検索してみてください。このクエリ文字列は実際には検索ワードを逆順にしたものになっているので、ページには「ninjas」と表示されていますが、実際には「sajnin」を検索しています。この手口はXKCDでネタとして使われて有名になりました。「これはまだましな方だ!最悪なのは」「U+202e」「らすれそ」「?たき起が何」「たっがやし何めて」データと処理インストラクション(事実上の実行可能コード)の混在は絶対によくありません。ユーザーが処理インストラクションを直接入力できてしまう場合は特にそうです。ユーザー入力をそのままページに表示すれば大きな問題になります。ほとんどのWeb開発者はそのことを知っているので、ユーザー入力からHTMLタグを除去してサニタイズしますが、ユーザー入力にUnicodeの制御文字が含まれる可能性にも注意が必要です。これは禁止用語やコンテンツのフィルタリングをすり抜ける初歩的な方法であり、語の文字を逆順にしてright-to-leftを語の最初に置いてオーバーライドするだけでできてしまいます。Right-to-leftをハックして悪意のあるコードを埋め込むのはさすがに無理かもしれませんが、気をつけないとコンテンツ表示を台無しにされる、つまりページ全体の文字が逆順で表示されるかもしれません。行われている対策は、ユーザーが入力するコンテンツの置き場所をinputフィールドやtextエリアに限定して、処理インストラクションがせめてページの他の部分に効かなくなるようにすることです。ひとつ、表示の処理インストラクションで特に大きな問題として、異体字(variation)セレクタがあります。色違いの絵文字ごとにコードを作成する事態を避けるために、Unicodeでは異体字セレクタで基本シンボルと色をミックスできるようになっています。異体字がすべて有効とは限りません。2017年1月、iOSのUnicode処理のバグが原因で、ある仕掛けを施したメッセージを送りつけるだけでiPhoneをリモートでクラッシュさせるといういたずらが発生しました。flag、1つの異体字セレクタ、そして1つのゼロが含まれていました。CoreTextは正しい異体字を取り出そうとしてパニックになり、iOSがクラッシュしました。このトリックはダイレクトメッセージやグループチャットの他、共有名刺にも通用し、iPadや一部のMacbookまでこの問題の影響を受けました。この悪用によるクラッシュの防止策はほとんどありませんでした。この種のバグは数年に1度は発生します。XやiOSをクラッシュさせる可能性のあるバグが見つかりました。したバグはOSのテキスト処理モジュールの奥底に潜んでいるため、一般のクライアントアプリ開発者には防止策がまったくありません。Codepointsリストで確認できます。Computers』をぜひチェックしてください。コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。チュートリアル第2版の監修および半分程度を翻訳、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れて更新翻訳中。enno.jpを運営。実は最近Go言語が好きで、Goで書かれたRubyライクなGoby言語のメンテナーでもある。仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。Storageを使ってはいけない(翻訳)#Tags#会社紹介#自社サービス#勉強会#Rails#PHP#デザイン#実績#週刊RailsウオッチCONTACTお気軽にご相談ください。(翻訳)CONTACTTechRachoでは、パートナーシップをご検討いただける方からのご連絡をお待ちしております。お気軽にご意見・ご相談ください。