
#98 Type Juggling
OSWEはじめました。あの達成感は一度味わったらやめられませんね。
円安?だからなんだよと。金なんぞくれてやるから勉強させろと半ばヤケで登録しました。
というわけで、しばらくはWebセキュリティをもっと深掘りしていこうと思います。今回は、Type Jugglingについて。
Type Juggling
Type Jugglingとは
Type Jugglingとは、PHPやJavaScriptのような動的型付け言語のもつ機能で、文脈によって値をいい感じに型変換してくれるものです。
例えば、PHPでは、Stringの値が数値として評価できるものであれば、IntとStringで足し算などの計算ができます。
$int = 10; // Int
$str = '10'; // String
$sum = $int + $str; // int(20)
型を意識しなくても上手いこと処理してくれるので、便利と言えば便利ですが、余計なおせっかいになることもあります。
以下の比較はいずれも、TRUEになります。
'123' == 123
'123a' == 123
'abc' == 0
1番目はいいとして、2、3番目は直感に反しませんか?これは、StringをIntに変換する際、文字列の前方から数値として評価できる部分だけを切りとるために起こります。
どのようなバグが生まれるか
これら不可解な型変換によって、認証バイパスなど意図しない挙動を引き起こす可能性が考えられます。
以下のように、パスワードの比較を誤るパターンはありそうです。
$password = "StrongP@ssword123"; // 平文のパスワード
$user_input = 0; // 入力値
if ($password == $user_input) {
echo "Welcome Admin!";
} else {
echo "Wrong password."
}
文字列「StrongP@ssword123」は、Intに変換されると0になるので、なんとかして入力値にIntの0を渡すことができればログインできてしまいます。このあたりは、システムの実装によって違うので一概に脆弱性になるとは言えません。
対策
PHP8.0以降は、暗黙の型変換にてこ入れが入って、ちょっとましになったようですが、依然Type Jugglingによる脆弱性が生まれる余地はあります。対策として、==ではなく===による厳密な比較を常に行うべきでしょう。自動型変換の恩恵はなくなりますが、思わぬ挙動を避けられます。特に、認証など重要な処理では、Type Jugglingが起こりうることを認識した上でプログラムを組むようにすべきです。
まとめ
Type Jugglingは、ついうっかり脆弱性を作り込んでしまうような危険性をはらんでいます。言語の仕様をしっかり理解してプログラムを組まないと、いつか自分の墓を掘ることになります。今回は主にPHPについて記述しましたが、JavaScriptやMySQLにも同様の機能があります。もっと深堀していきたいです。
参考
PHP Magic Tricks: Type Juggling(OWASP)
Type Juggling (PayloadAllTheThings)
EOF