Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
164
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

@ariaki

PHPでパスワード比較に==とか===使っちゃだめって知ってた?

PHPerの皆さん、重要な文字列を入力データと保管情報を比較するときに比較演算子("=="とか"===")使ってませんか?
これ実は使っちゃだめなので、気をつけましょう。

なぜだめなの?

(2020/8/31修正) 関数名をtypoしていたため修正しました。(正)memcmp・(誤)strcmpです。

PHPを含む多くの言語では、文字列を比較する際に内部で memcmp() を使います。
通常の(厳密なセキュリティを必要としない)ケースでは、比較演算子を使うことはまったく問題ありません。
パスワードなど絶対に推測されてはいけない文字列を比較する場合、この関数は脆弱といえます。
memcmp() は内部で1バイトずつ比較検証するため、応答時間をもとに先頭から何文字正解だったか推測できます。
このような攻撃を「タイミング攻撃」といいます。

どうすればいいの?

PHPでは、ハッシュ値を用いて文字列を比較する hash_equals() という関数が用意されています。
関数の説明にもきちんと「Timing attack safe string comparison」と書かれています。

パスワードを扱う際の正しい実装

(2020/8/28追記) @anirfa さんのコメントをもとに追記しました。

ここまでは平文で保管された「重要な文字列」を扱う際の注意点でした。
たとえばパスワードなどの第三者から読み取らせてはいけない情報はそもそも平文で保管せず、ハッシュ化して保管すべきです。
PHPにはパスワード管理のために以下のような関数がありますので、そちらを使ってください。

実装をのぞいてみた

本当に比較演算子で strcmp() が使われてるかPHPソースコードをみてみましょう。

zend_string.h#L316-L335

zend_string.h
#if defined(__GNUC__) && (defined(__i386__) || (defined(__x86_64__) && !defined(__ILP32__)))
BEGIN_EXTERN_C()
ZEND_API zend_bool ZEND_FASTCALL zend_string_equal_val(zend_string *s1, zend_string *s2);
END_EXTERN_C()
#else
static zend_always_inline zend_bool zend_string_equal_val(zend_string *s1, zend_string *s2)
{
    return !memcmp(ZSTR_VAL(s1), ZSTR_VAL(s2), ZSTR_LEN(s1));
}
#endif

static zend_always_inline zend_bool zend_string_equal_content(zend_string *s1, zend_string *s2)
{
    return ZSTR_LEN(s1) == ZSTR_LEN(s2) && zend_string_equal_val(s1, s2);
}

static zend_always_inline zend_bool zend_string_equals(zend_string *s1, zend_string *s2)
{
    return s1 == s2 || zend_string_equal_content(s1, s2);
}

zend_string_equals->zend_string_equal_content->zend_string_equal_val->memcmpが呼び出されていますね。
※インラインアセンブラが使える場合の処理(zend_string.c#L396-431)の説明は割愛します

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
164
Help us understand the problem. What are the problem?