🍺

表示方向の制御文字を調べてみた話

2021/11/22に公開

きっかけ

2021年11月に以下のような話がツイッターで流れてきました。

https://www.lightbluetouchpaper.org/2021/11/01/trojan-source-invisible-vulnerabilities/

Trojanはトロイの木馬の事ですが、ITのセキュリティで言うところの一般的なトロイの木馬とは若干趣が異なる話です。
(もちろん、昔話のトロイの木馬そのものの話では無いです)

はじめに

以下に【nobokko】という単語に見える何かを用意しました。

‮ok⁦nоbοk

通常のブラウザでみている限りは恐らくnobokkoと読めたかと思います。

実際には

[U+202E]ok[U+2066]nоbοk

という文字列がブラウザには読み込まれています。
また、nの次の【o】およびbの次の【o】の字も、キーボードから通常入力されるであろうoでは無い、別の【oっぽい】文字です。

oの文字はこのサイトで違和感の無いものをチョイスしました。なお、選んだ文字は恐らく環境や利用フォントに依存するため、表示されなかったり明らかにoに見えない文字に見えている可能性もありえます。

実際の文字列(コンピュータが認識する文字列)と視覚情報として人が認識する文字が一致しない、というのがこの件の大まかな内容です。たぶん。

なお、VSCode等で開くと制御文字が文字コードとして表示され、代わりに表示制御を行わない為、設定をコッテリ編集していない限りはすぐ気づくかと思います。

とはいえ、こういう情報を仕入れてしまったからにはトータルでは100人単位で触ってるであろうレガシーコードの確認はしておくべきだろうとは思うわけです。

事前補足

既存コードの調査に必要な情報としては存在が分かるだけでよく、特に制御文字を使いこなすことを目的とはしていないため、詳細には調べていません。

制御文字

Right-to-Left

双方向テキストと呼ばれるカテゴリらしいです。BiDi(バイダイ)。

右から左に「表示」されるようになります。
また、カッコに相当する文字は表示の際に反転もするようです。

U+200F Right-to-Left Mark 【RLM】

例:[U+200F] }【 abcde 12345 [U+202C] 67890

‏ }【 abcde 12345 ‬ 67890

U+202B Right-to-Left Embedding 【RLE】

RLMと比べると適用範囲が強いです。

例:[U+202B] }【 abcde 12345 [U+202C] 67890

‫ }【 abcde 12345 ‬ 67890

U+202E Right-to-Left Override 【RLO】

RLMと比べると適用範囲が強いです。

例:[U+202E] }【 abcde 12345 [U+202C] 67890

‮ }【 abcde 12345 ‬ 67890

U+2067 Right-to-Left isolate 【RLI】

例:[U+2067] }【 abcde 12345 [U+202C] 67890

⁧ }【 abcde 12345 ‬ 67890

制御文字が埋まっていないか調べる方法

その1

linux系であればgrepコマンドが利用できました。

grep -E "(\x{200f}|\x{202b}|\x{202e}|\x{2067})" ファイル名とか

その2

VSCodeが使用できるのであれば、普段使用しているであろう検索条件に制御文字そのものを入力すると検索されました。

まとめ

調べてみると問題そのものは少なくとも10年前から提唱されていて、なぜ今?という気持ちですが、手口が巧妙化してきたんですかね?

当然左から右方向の制御文字等もあるわけですが、それらの制御文字だけが使われていて問題になりそうな気がしなかったので今回は割愛しました。

また、これははじめに書いてもよかったのですが、GitHubからソースを閲覧した場合は制御文字が含まれる行の左に警告マークが出てました。

お疲れさまでした。

Discussion