From 4e9dfd6018eee70f5c55e22d102ddbfb74fab52e Mon Sep 17 00:00:00 2001 From: xboard <147830212+cedar2025@users.noreply.github.com> Date: Fri, 22 May 2026 22:05:33 +0800 Subject: [PATCH] fix(security): harden registration email code validation --- app/Services/Auth/RegisterService.php | 7 +- .../Services/Auth/RegisterServiceTest.php | 75 +++++++++++++++++++ 2 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 tests/Unit/Services/Auth/RegisterServiceTest.php diff --git a/app/Services/Auth/RegisterService.php b/app/Services/Auth/RegisterService.php index 78d207e..31d39d1 100644 --- a/app/Services/Auth/RegisterService.php +++ b/app/Services/Auth/RegisterService.php @@ -82,10 +82,13 @@ class RegisterService // 检查邮箱验证 if ((int) admin_setting('email_verify', 0)) { - if (empty($request->input('email_code'))) { + $emailCode = $request->input('email_code'); + if (!is_scalar($emailCode) || !preg_match('/^\d{6}$/', (string) $emailCode)) { return [false, [422, __('Email verification code cannot be empty')]]; } - if ((string) Cache::get(CacheKey::get('EMAIL_VERIFY_CODE', $request->input('email'))) !== (string) $request->input('email_code')) { + + $cachedEmailCode = Cache::get(CacheKey::get('EMAIL_VERIFY_CODE', $request->input('email'))); + if ($cachedEmailCode === null || !hash_equals((string) $cachedEmailCode, (string) $emailCode)) { return [false, [400, __('Incorrect email verification code')]]; } } diff --git a/tests/Unit/Services/Auth/RegisterServiceTest.php b/tests/Unit/Services/Auth/RegisterServiceTest.php new file mode 100644 index 0000000..3d8cffa --- /dev/null +++ b/tests/Unit/Services/Auth/RegisterServiceTest.php @@ -0,0 +1,75 @@ + 1, + 'email_whitelist_enable' => 0, + 'email_gmail_limit_enable' => 0, + 'stop_register' => 0, + 'invite_force' => 0, + 'captcha_enable' => 0, + 'register_limit_by_ip_enable' => 0, + ]); + + $this->service = app(RegisterService::class); + } + + public function test_validate_register_rejects_missing_cached_email_code(): void + { + [$success, $result] = $this->service->validateRegister($this->makeRequest([ + 'email_code' => '123456', + ])); + + $this->assertFalse($success); + $this->assertSame(400, $result[0]); + } + + public function test_validate_register_rejects_boolean_email_code(): void + { + [$success, $result] = $this->service->validateRegister($this->makeRequest([ + 'email_code' => false, + ])); + + $this->assertFalse($success); + $this->assertSame(422, $result[0]); + } + + public function test_validate_register_accepts_matching_cached_email_code(): void + { + Cache::put(CacheKey::get('EMAIL_VERIFY_CODE', 'user@example.com'), 123456, 300); + + [$success, $result] = $this->service->validateRegister($this->makeRequest([ + 'email_code' => '123456', + ])); + + $this->assertTrue($success); + $this->assertNull($result); + } + + private function makeRequest(array $overrides = []): Request + { + return Request::create('/api/v1/passport/auth/register', 'POST', array_merge([ + 'email' => 'user@example.com', + 'password' => 'password123', + ], $overrides)); + } +}