Pythonで「str.lower()」を使うと思わぬ脆弱性に?開発者が知っておくべき危険な落とし穴
When str.lower() is a security vulnerability in Python – Seth Larson
When str.lower() is a security vulnerability in Python – Seth Larson
Pythonにおいて文字列の正規化によく使われる「str.lower()」ですが、実はセキュリティ上の脆弱性を引き起こす可能性があることをご存知でしょうか。Seth Larson氏による本記事では、特にUnicode文字の取り扱いにおいて、期待した動作と異なる結果が導かれることで発生するセキュリティリスクについて詳しく解説されています。単なる大文字・小文字の変換として片付けず、バリデーションやセキュリティが関わる処理でこれを用いる際は、Unicodeの特性を十分に考慮する必要があります。
だからこそstr.lower()を呼び出すことが実装と仕様の乖離、ひいては脆弱性につながるんだよ。
これがなぜ単なるデータの不整合を生むバグじゃなくて「脆弱性」なのか、その説明がどこかにないものかな。自分には、脆弱性って言うならそのバグを突いてエクスプロイトを作成する現実的な手段があるように聞こえるんだけど、この分野に詳しくない身としてはそれが全く見えてこないんだ。
バージョン管理の悪夢だな
こういう馬鹿げたことが、PythonのTLS実装に関わる人たちに、SANの「定義された」仕組み(Subject Alternative Nameの「Alternative」は、複数ある中の代替という意味じゃない。X.509はもともとX.500システム用で、インターネットがそれを流用したから、インターネットから見て「代替の」名前という意味なんだ)を理解してもらうのがいかに重要だったかという大きな理由だよ。これらはDNS名であって、人間が読むためのテキストとして解釈しちゃいけないものなんだ。だからUnicodeに「デコード」するなんて間違いなくナンセンス。Pythonはすごくやりたがってたし、以前はそうしていたか、少なくともそうしようと提案してたと思うけどね。
SANのDnsNameがDNS上の名前にどう一致するかというルールは、ミスを防ぐためにものすごくシンプルだよ。ワイルドカードを1つ(ASCIIコード42の*はDNSラベル1つ分にマッチする)処理するだけで、あとは文字通りのバイト比較だ。バイトの意味なんて気にしちゃダメ。バイトが完全に一致するか、一致しないならそれで終わり。
IDNでホスティングしてるなら、".lower()"のスクワッティングを狙うやつらを探しておいたほうがいいかもな。
Pythonでß.upper()が"SS"になるのを知った時もびっくりしたよ。場合によっては予期しない挙動になるからね(upperを呼び出して文字列の長さが変わっちゃうとさ)
昔Spotifyで起きたセキュリティインシデントを思い出したよ https://engineering.atspotify.com/2013/06/creative-usernames
それはちょっと大げさじゃないかな。string.lower()自体はセキュリティ脆弱性じゃないよ。仕様に従っていないことこそがセキュリティ脆弱性なんだ。
それって実際にある話なの?
「IDNA 2003の処理が異なる2つの実装をユーザー入力として含んでいるソフトウェアシステムがある場合」って、それ現実にある話なの?誰か実際にそんなことやってるのか?