とある OAuth2 サーバサイド実装にセキュリティ的に良くなさそうな点があったため指摘した時の話

「スタバで注文するのはいつも Venti」でおなじみの fujimura です。

以前、OAuth2 のサーバサイド実装について調査していた時にアクセストークンは PHP の場合は openssl_random_pseudo_bytes で生成することが定石らしいということを調べていて感じていました。(他の言語でも OpenSSL のような暗号学的に強いアルゴリズムを持ったライブラリで生成することが望ましいと思われます。)

$randomData = openssl_random_pseudo_bytes(20);
return bin2hex(
    openssl_random_pseudo_bytes(
        $this->randomLength
    )
);
$bytes = openssl_random_pseudo_bytes($len, $strong);

ところがそんな中に良くなさそうな実装がありました。

$accessToken->setAccessToken(md5(uniqid(null, true)))

PHP における uniqueid

マイクロ秒単位の現在時刻にもとづいた、接頭辞つきの一意な ID を取得

できるのですが、

警告 この関数は、ランダムな値を作るわけでもなければ予測不能な文字列を作るわけでもありません。 セキュリティを確保するためにこの関数を使ってはいけません。 予測不能でセキュアな ID を作りたい場合は、暗号学的にセキュアな乱数やハッシュを作る関数を利用しましょう。

と記述されているとおり、セキュアではない実装となっています。

そこで作者にその旨を伝えることにしました。

引用だけの拙い issue でしたが、指摘後にすばやく対応していただけました。

$accessToken->setAccessToken(md5(openssl_random_pseudo_bytes(256)))

英語ができなくても引用だけで伝えることができたのはいい経験となりました。