Skip to content

Issue #1306: パスワードハッシュの自動マイグレーション機能の追加(Argon2id対応)#1374

Open
nanasess wants to merge 6 commits intoEC-CUBE:masterfrom
nanasess:fix/issue-1306-password-rehash
Open

Issue #1306: パスワードハッシュの自動マイグレーション機能の追加(Argon2id対応)#1374
nanasess wants to merge 6 commits intoEC-CUBE:masterfrom
nanasess:fix/issue-1306-password-rehash

Conversation

@nanasess
Copy link
Copy Markdown
Contributor

@nanasess nanasess commented Mar 24, 2026

Summary

Closes #1306

ログイン成功時に旧アルゴリズム(SHA1/HMAC-SHA256)のパスワードハッシュを現在の設定アルゴリズムへ自動マイグレーションする機能を追加。

PASSWORD_HASH_ALGOS のデフォルト値を PASSWORD_DEFAULT(bcrypt)に変更し、PHP標準の password_hash()/password_verify()/password_needs_rehash() を使用した最新アルゴリズムへの透過的な移行が可能になります。

マイグレーションパス

SHA1 (2.11未満) → HMAC-SHA256 (2.11以降) → bcrypt/Argon2id (password_hash)

変更内容

ファイル 変更内容
data/class/util/SC_Utils.php sfIsPasswordHashAlgos(), sfNeedsReHash(), sfReHashPassword() 追加。sfGetHashString(), sfIsMatchHashPassword()password_hash() 形式に対応
data/class/SC_Customer.php 会員ログイン時の自動マイグレーション処理追加(2箇所)
data/class/pages/admin/LC_Page_Admin_Index.php 管理者ログイン時の自動マイグレーション処理追加
data/class/SC_Initial.php PASSWORD_HASH_ALGOS のデフォルト値を PASSWORD_DEFAULT に変更
html/install/index.php インストーラのアルゴリズム選択を PASSWORD_DEFAULT に簡素化
docker-compose*.yml 環境変数 PASSWORD_HASH_ALGOS2yPASSWORD_DEFAULT の値)に変更
tests/config.php テスト設定を PASSWORD_DEFAULT に変更
eccube_install.sh インストールスクリプトを PASSWORD_DEFAULT に変更
tests/class/util/SC_Utils/SC_Utils_sfNeedsReHash_authTypeHmacTest.php 新規: HMAC + password_hash形式テスト (11テスト)
tests/class/util/SC_Utils/SC_Utils_sfNeedsReHash_authTypePlainTest.php 新規: PLAIN用テスト (2テスト)
tests/class/util/SC_Utils/SC_Utils_sfIsMatchHashPassword_authTypePlainTest.php コメントアウト解除、@group auth_type_plain 追加
tests/require_auth_type_plain.php 新規: AUTH_TYPE=PLAIN用カスタムbootstrap
.github/workflows/unit-tests.yml auth_type_plain グループの除外と個別実行ステップ追加

設定方法

// data/config/config.php

// PHPデフォルト(現在はbcrypt、将来自動的に強化される) ← 新デフォルト
define('PASSWORD_HASH_ALGOS', PASSWORD_DEFAULT);

// Argon2id を明示指定
define('PASSWORD_HASH_ALGOS', PASSWORD_ARGON2ID);

// 従来のHMAC-SHA256を維持する場合
define('PASSWORD_HASH_ALGOS', 'sha256');

後方互換性

  • 既存の SHA1 ハッシュ(2.11未満): ログイン時に自動マイグレーション
  • 既存の HMAC-SHA256 ハッシュ(2.11以降): ログイン時に自動マイグレーション
  • PASSWORD_HASH_ALGOS = 'sha256' を明示指定すれば従来動作を維持可能

Test plan

  • PHPUnit sfNeedsReHash テスト通過(HMAC: 11テスト, PLAIN: 2テスト)
  • PHPUnit 既存 sfIsMatchHashPassword テスト通過(リグレッションなし)
  • PHPUnit全テスト通過(MySQL & PostgreSQL)
  • E2Eテスト全テスト通過(MySQL & PostgreSQL)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • 新機能

    • ログイン時にパスワードが古い形式の場合、自動で安全なハッシュへ移行する再生成機能を追加。
  • 改善

    • デフォルトのパスワードハッシュアルゴリズムをPHP標準(PASSWORD_DEFAULT)へ変更し、よりモダンな方式へ対応。
  • テスト

    • 平文・HMAC・password_hash系を含む認証関連の包括的なテストを追加・拡充。
  • Chore

    • テスト実行ワークフローを調整し、平文認証系テストを専用ジョブで分離。Docker環境のハッシュ設定も更新。

ログイン成功時に旧アルゴリズム(SHA1/HMAC-SHA256)のパスワードハッシュを
現在の設定アルゴリズムへ自動マイグレーションする機能を追加。

PASSWORD_HASH_ALGOS に PASSWORD_DEFAULT や PASSWORD_ARGON2ID を設定することで
PHP標準の password_hash()/password_verify()/password_needs_rehash() を使用した
最新アルゴリズムへの透過的な移行が可能になる。

- sfIsPasswordHashAlgos(): PASSWORD_HASH_ALGOS がpassword_hash()対応か判定
- sfNeedsReHash(): 再ハッシュ判定(password_needs_rehash()活用)
- sfReHashPassword(): 再ハッシュ実行
- sfGetHashString()/sfIsMatchHashPassword(): password_hash形式のサポート追加
- 会員/管理者ログイン時の自動マイグレーション処理追加
- AUTH_TYPE=PLAIN用テストのCI個別実行対応

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 24, 2026

📝 Walkthrough

Walkthrough

ログイン時に既存ハッシュを検証し、必要ならば新しいハッシュへ自動で再生成・DB更新する自動マイグレーション機能を追加。関連ユーティリティ、初期設定、コンテナ環境、テスト、CIワークフローも併せて更新。

Changes

Cohort / File(s) Summary
ハッシュ検証・再ハッシュAPI
data/class/util/SC_Utils.php
sfGetHashString()の挙動調整($saltデフォルト化、AUTH_TYPE分岐)、sfIsMatchHashPassword()を拡張してpassword_hash()判定/検証を追加、sfIsPasswordHashAlgos(), sfNeedsReHash(), sfReHashPassword()を新規実装。定数PASSWORD_HASH_SALT_DUMMYを追加。
ユーザ/管理者ログインの自動マイグレーション
data/class/SC_Customer.php, data/class/pages/admin/LC_Page_Admin_Index.php
認証成功時にsfNeedsReHash()で判定し、必要ならsfReHashPassword()で新ハッシュ生成後にdtb_customer/dtb_memberをUPDATEしてインメモリも置換する処理を追加。
初期設定・インストール生成値変更
data/class/SC_Initial.php, eccube_install.sh, html/install/index.php, tests/config.php
PASSWORD_HASH_ALGOSのデフォルトを文字列'sha256'からPASSWORD_DEFAULTへ変更(生成するconfigやインストーラ出力も同様に更新)。
Docker環境の環境変数更新
docker-compose.yml, docker-compose.mysql.yml, docker-compose.pgsql.yml, docker-compose.sqlite3.yml
コンテナ環境変数PASSWORD_HASH_ALGOSsha256から2yへ変更(bcrypt指定に合わせた値へ更新)。
CI分離(平文テスト)
.github/workflows/unit-tests.yml, tests/require_auth_type_plain.php
auth_type_plainテストグループを一般実行から除外し、専用ジョブ/ブートストラップ(tests/require_auth_type_plain.php)で個別実行するようにCIを分離。
テスト追加・修正
tests/class/util/SC_Utils/..., tests/config.php, tests/require_auth_type_plain.php
sfNeedsReHash/sfIsMatchHashPassword/sfReHashPasswordのHMAC/平文/パスワードハッシュ対応を検証する多数の新規テストを追加。平文用テストに@group auth_type_plainを付与し専用bootstrapを追加。

Sequence Diagram

sequenceDiagram
    participant User as ユーザー
    participant Server as サーバー<br/>(認証処理)
    participant DB as データベース<br/>(dtb_customer / dtb_member)

    User->>Server: ログイン要求 (ID + パスワード)
    Server->>DB: 顧客/会員情報取得 (password, salt)
    DB-->>Server: 取得済みハッシュ返却
    Server->>Server: sfIsMatchHashPassword(pass, hash, salt)
    alt 検証失敗
        Server-->>User: 認証失敗
    else 検証成功
        Server->>Server: sfNeedsReHash(hash, salt)
        alt 再ハッシュ不要
            Server-->>User: 認証成功
        else 再ハッシュ必要
            Server->>Server: sfReHashPassword(pass) -> newHash, newSalt
            Server->>DB: UPDATE password, salt WHERE id=...
            DB-->>Server: 更新完了
            Server-->>User: 認証成功 (自動マイグレーション済)
        end
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Suggested labels

BC Break

Poem

🐰 古い鍵はやさしく見送り
新しい鍵をそっとかけるよ🔐
ログインひとつで変わる道筋
ぼくの足跡で安全を刻む
にんまり、跳ねて祝おう!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR タイトルは「パスワードハッシュの自動マイグレーション機能の追加(Argon2id対応)」であり、変更内容の主要な目的を明確に反映しており、具体的で説明的である。
Linked Issues check ✅ Passed PR の実装は #1306 の要件をほぼ完全に満たしており、sfNeedsReHash、sfReHashPassword、sfIsPasswordHashAlgos の追加、ログイン時の自動マイグレーション処理(SC_Customer.php、LC_Page_Admin_Index.php)、デフォルトアルゴリズムの PASSWORD_DEFAULT への変更、および包括的なテストが実装されている。
Out of Scope Changes check ✅ Passed すべての変更は #1306 の要件に直接関連しており、password_hash 対応の自動マイグレーション機能実装、設定更新、テスト追加などであり、範囲外の変更は見られない。

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 24, 2026

Codecov Report

❌ Patch coverage is 57.69231% with 22 lines in your changes missing coverage. Please review.
✅ Project coverage is 54.35%. Comparing base (08f44be) to head (2715dde).
⚠️ Report is 8 commits behind head on master.

Files with missing lines Patch % Lines
data/class/util/SC_Utils.php 69.04% 13 Missing ⚠️
data/class/SC_Customer.php 10.00% 9 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1374      +/-   ##
==========================================
- Coverage   54.42%   54.35%   -0.08%     
==========================================
  Files          84       84              
  Lines       10817    10859      +42     
==========================================
+ Hits         5887     5902      +15     
- Misses       4930     4957      +27     
Flag Coverage Δ
tests 54.35% <57.69%> (-0.08%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

nanasess and others added 2 commits March 24, 2026 17:21
新規インストール時およびデフォルト設定で、password_hash() による
bcrypt ハッシュが使用されるようになる。
PHP のバージョンアップに伴い PASSWORD_DEFAULT が変更された場合、
自動的に最新の推奨アルゴリズムが適用される。

- SC_Initial.php, tests/config.php, eccube_install.sh: PASSWORD_DEFAULT に変更
- html/install/index.php: インストーラのアルゴリズム選択を PASSWORD_DEFAULT に簡素化
- docker-compose*.yml: 環境変数を '2y' (PASSWORD_DEFAULT の値) に変更
- sfIsMatchHashPassword(): レガシーハッシュ検証時は常に hash_hmac('sha256') を使用するよう修正

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
php_unit_method_casing ルールに準拠するよう、テストメソッド名から
アンダースコアを除去してキャメルケースに変更。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
.github/workflows/unit-tests.yml (1)

86-88: auth_type_plain をディレクトリまで固定すると CI の取りこぼしが出ます。

この step は main run の --exclude-group auth_type_plain と対になっているので、ここが唯一の実行経路です。tests/class/util/SC_Utils/ まで絞ると、別ディレクトリに @group auth_type_plain を追加した瞬間に CI から漏れます。グループで切り分ける方針ならパス指定は外すか、少なくとも tests/class/ まで広げたいです。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/unit-tests.yml around lines 86 - 88, The CI step currently
hardcodes the test path in the docker command (the phpunit invocation that uses
--bootstrap tests/require_auth_type_plain.php and targets
tests/class/util/SC_Utils/), which will miss any other tests marked with `@group`
auth_type_plain; update the phpunit command to remove the specific directory
filter (or at least broaden it to tests/class/) so it relies on --group
auth_type_plain to select tests (i.e., keep the --bootstrap
tests/require_auth_type_plain.php and --group auth_type_plain flags but change
the target path passed to phpunit to either nothing or tests/class/ instead of
tests/class/util/SC_Utils/).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@data/class/util/SC_Utils.php`:
- Around line 1774-1789: sfGetHashString's optional salt parameter currently
diverges from sfIsMatchHashPassword's legacy-empty-salt handling, breaking
verification for empty-salt hashes; preserve the public signature and ensure
generation follows the same legacy SHA1 path when $salt == '' by routing
sfGetHashString($str, '') to the same legacy algorithm used by
sfIsMatchHashPassword (use AUTH_MAGIC/legacy SHA1 logic) instead of the HMAC
branch that uses PASSWORD_HASH_ALGOS, and ensure constants AUTH_MAGIC and
PASSWORD_HASH_ALGOS are used consistently so existing plugins keep working.
- Around line 1779-1781: The code currently calls hash_hmac(PASSWORD_HASH_ALGOS,
...) even when sfIsPasswordHashAlgos() is false, which passes unsupported
password_hash-only algos (e.g. argon2id) into hash_hmac; change the logic in
SC_Utils.php around SC_Utils_Ex::sfIsPasswordHashAlgos() so that: (1) when
sfIsPasswordHashAlgos() is true continue to use password_hash with
PASSWORD_HASH_ALGOS; (2) when false, distinguish legacy HMAC-allowed algos from
unsupported config and map to a safe HMAC algorithm (e.g. 'sha256') before
calling hash_hmac; update all hash_hmac(PASSWORD_HASH_ALGOS, ...) sites
(including the other occurrences noted and any callers in SC_Customer.php and
LC_Page_Admin_Index.php) to use this whitelist-or-fallback approach rather than
passing PASSWORD_HASH_ALGOS directly.

In `@html/install/index.php`:
- Line 1017: The generated config currently writes PASSWORD_HASH_ALGOS as a
string literal (from $algos = '...') causing sfIsPasswordHashAlgos() to fail
because password_algos() returns algorithm names; change the generator to emit
the constant reference instead of a quoted string: set the code that assigns
$algos (and the later generation that writes define('PASSWORD_HASH_ALGOS', ...))
to use the PASSWORD_DEFAULT constant (unquoted) so the produced line is
define('PASSWORD_HASH_ALGOS', PASSWORD_DEFAULT); ensuring
sfIsPasswordHashAlgos() and password_hash() use the correct algorithm values.

In `@tests/require_auth_type_plain.php`:
- Around line 1-6: tests/require_auth_type_plain.php defines the AUTH_TYPE
constant as 'PLAIN' before including other files, but
data/mtb_constants_init.php unconditionally defines AUTH_TYPE = "HMAC", causing
E_NOTICE on redefinition; update data/mtb_constants_init.php to only define
AUTH_TYPE if it is not already defined (wrap the define('AUTH_TYPE', 'HMAC') in
an if (!defined('AUTH_TYPE')) check) so existing definitions from
tests/require_auth_type_plain.php are respected and notices are avoided.

---

Nitpick comments:
In @.github/workflows/unit-tests.yml:
- Around line 86-88: The CI step currently hardcodes the test path in the docker
command (the phpunit invocation that uses --bootstrap
tests/require_auth_type_plain.php and targets tests/class/util/SC_Utils/), which
will miss any other tests marked with `@group` auth_type_plain; update the phpunit
command to remove the specific directory filter (or at least broaden it to
tests/class/) so it relies on --group auth_type_plain to select tests (i.e.,
keep the --bootstrap tests/require_auth_type_plain.php and --group
auth_type_plain flags but change the target path passed to phpunit to either
nothing or tests/class/ instead of tests/class/util/SC_Utils/).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e6dbe405-b453-4931-8088-2788054cfea9

📥 Commits

Reviewing files that changed from the base of the PR and between 9a599f3 and 6f6aa9a.

📒 Files selected for processing (16)
  • .github/workflows/unit-tests.yml
  • data/class/SC_Customer.php
  • data/class/SC_Initial.php
  • data/class/pages/admin/LC_Page_Admin_Index.php
  • data/class/util/SC_Utils.php
  • docker-compose.mysql.yml
  • docker-compose.pgsql.yml
  • docker-compose.sqlite3.yml
  • docker-compose.yml
  • eccube_install.sh
  • html/install/index.php
  • tests/class/util/SC_Utils/SC_Utils_sfIsMatchHashPassword_authTypePlainTest.php
  • tests/class/util/SC_Utils/SC_Utils_sfNeedsReHash_authTypeHmacTest.php
  • tests/class/util/SC_Utils/SC_Utils_sfNeedsReHash_authTypePlainTest.php
  • tests/config.php
  • tests/require_auth_type_plain.php

nanasess and others added 2 commits March 25, 2026 16:16
dtb_member.salt の NOT NULL 制約により、password_hash() 形式で
再ハッシュ時に空文字列を設定すると PostgreSQL/SQLite3 で
NOT NULL 制約違反が発生する問題を修正。

SC_Utils::PASSWORD_HASH_SALT_DUMMY 定数を導入し、
password_hash() 使用時はダミー値を設定するようにした。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
sfIsPasswordHashAlgos() が false の場合のフォールバックで
PASSWORD_HASH_ALGOS をそのまま hash_hmac() に渡していたが、
PASSWORD_HASH_ALGOS が password_hash() 専用アルゴリズム(argon2id等)
の場合に hash_hmac() が失敗する可能性があった。

sfIsMatchHashPassword() と同様に 'sha256' をハードコードして
レガシーHMACパスの安全性を確保する。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@nanasess nanasess marked this pull request as ready for review March 25, 2026 09:16
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
data/class/util/SC_Utils.php (1)

1808-1825: hash_equals() による定時間比較の統一

password_verify() の分岐は内部で定時間比較を行いますが、PLAIN および レガシーハッシュ の分岐は === を使用しているため、タイミング攻撃に対して脆弱です。認証処理では両方の分岐を hash_equals() に統一し、すべての比較を定時間で実行することが安全です。

修正案
         if (AUTH_TYPE == 'PLAIN') {
-            return $pass === $hashpass;
+            return hash_equals($hashpass, $pass);
         }
         // password_hash() 形式のハッシュを検出 ($2y$..., $argon2id$... 等)
         $info = password_get_info($hashpass);
         if ($info['algo'] !== null && $info['algo'] !== 0) {
             return password_verify($pass, $hashpass);
         }
         // 既存ロジック: HMAC-SHA256 / SHA1
         if (empty($salt)) {
             // 旧バージョン(2.11未満)からの移行を考慮
             $hash = sha1($pass.':'.AUTH_MAGIC);
         } else {
             // レガシーハッシュの検証は常にHMAC-SHA256を使用
             $hash = hash_hmac('sha256', $pass.':'.AUTH_MAGIC, $salt);
         }

-        return $hash === $hashpass;
+        return hash_equals($hashpass, $hash);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@data/class/util/SC_Utils.php` around lines 1808 - 1825, The PLAIN and
legacy-hash branches use === which is vulnerable to timing attacks; change those
equality checks to constant-time comparisons using hash_equals. Specifically, in
the AUTH_TYPE == 'PLAIN' branch replace "return $pass === $hashpass;" with a
hash_equals call (e.g. return hash_equals((string)$hashpass, (string)$pass);),
and after computing the legacy $hash (both the sha1 and hash_hmac branches)
replace "return $hash === $hashpass;" with return hash_equals((string)$hashpass,
(string)$hash); while keeping the password_verify($pass, $hashpass) branch
unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@data/class/util/SC_Utils.php`:
- Around line 1846-1870: The code currently treats any non-password_hash()
configuration as legacy; update sfNeedsReHash (and the similar block around
sfReHashPassword) to only silently treat the explicit legacy algorithm 'sha256'
as legacy, and for any other unsupported password_hash algorithm (i.e. when
SC_Utils_Ex::sfIsPasswordHashAlgos() returns false but the configured algorithm
is not 'sha256') raise a clear configuration error via SC_Helper_HandleError (do
not fall back to HMAC-SHA256); locate the checks in sfNeedsReHash and the
corresponding logic in sfReHashPassword, add an explicit branch that checks the
configured algorithm string, allow legacy only for 'sha256', and call
SC_Helper_HandleError to report unsupported password_hash() algorithm
configuration.
- Around line 1833-1836: The sfIsPasswordHashAlgos function currently calls
in_array(PASSWORD_HASH_ALGOS, password_algos()) using loose comparison; change
the in_array call in sfIsPasswordHashAlgos to pass the strict=true third
argument so it uses strict type comparison (in_array(PASSWORD_HASH_ALGOS,
password_algos(), true)) to avoid false positives when PASSWORD_HASH_ALGOS is
non-string or falsy.

---

Nitpick comments:
In `@data/class/util/SC_Utils.php`:
- Around line 1808-1825: The PLAIN and legacy-hash branches use === which is
vulnerable to timing attacks; change those equality checks to constant-time
comparisons using hash_equals. Specifically, in the AUTH_TYPE == 'PLAIN' branch
replace "return $pass === $hashpass;" with a hash_equals call (e.g. return
hash_equals((string)$hashpass, (string)$pass);), and after computing the legacy
$hash (both the sha1 and hash_hmac branches) replace "return $hash ===
$hashpass;" with return hash_equals((string)$hashpass, (string)$hash); while
keeping the password_verify($pass, $hashpass) branch unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 49e75c8a-9fff-43e2-a6de-c5024af7f19d

📥 Commits

Reviewing files that changed from the base of the PR and between 6f6aa9a and ec3bb05.

📒 Files selected for processing (2)
  • data/class/util/SC_Utils.php
  • tests/class/util/SC_Utils/SC_Utils_sfNeedsReHash_authTypeHmacTest.php
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/class/util/SC_Utils/SC_Utils_sfNeedsReHash_authTypeHmacTest.php

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
data/class/util/SC_Utils.php (1)

1817-1826: タイミング攻撃対策として hash_equals() の使用を推奨します。

Line 1825 で === を使用してハッシュ値を比較していますが、これはタイミングセーフではありません。理論的には、攻撃者が応答時間の差異を利用してハッシュ値を推測する可能性があります。

password_verify() は内部でタイミングセーフな比較を行いますが、レガシーパス(SHA1/HMAC-SHA256)では hash_equals() を使用することを推奨します。

♻️ タイミングセーフな比較への修正案
         // レガシーハッシュの検証は常にHMAC-SHA256を使用
             $hash = hash_hmac('sha256', $pass.':'.AUTH_MAGIC, $salt);
         }

-        return $hash === $hashpass;
+        return hash_equals($hashpass, $hash);
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@data/class/util/SC_Utils.php` around lines 1817 - 1826, Replace the
non-timing-safe strict comparison (return $hash === $hashpass;) with a
timing-safe comparison using PHP's hash_equals; specifically, in the SC_Utils
function where $hash and $hashpass are computed, return
hash_equals((string)$hashpass, (string)$hash); so legacy SHA1/HMAC-SHA256 checks
use a constant-time comparison and avoid type warnings by casting to string.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@data/class/util/SC_Utils.php`:
- Around line 1817-1826: Replace the non-timing-safe strict comparison (return
$hash === $hashpass;) with a timing-safe comparison using PHP's hash_equals;
specifically, in the SC_Utils function where $hash and $hashpass are computed,
return hash_equals((string)$hashpass, (string)$hash); so legacy SHA1/HMAC-SHA256
checks use a constant-time comparison and avoid type warnings by casting to
string.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3571022a-1f0e-4d2e-aea0-a98e9228cb5f

📥 Commits

Reviewing files that changed from the base of the PR and between ec3bb05 and 2715dde.

📒 Files selected for processing (1)
  • data/class/util/SC_Utils.php

@nanasess nanasess enabled auto-merge March 26, 2026 08:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

パスワードハッシュの自動マイグレーション機能の追加(Argon2id対応)

1 participant