fix(auth): reject OAuth logins without valid provider IDs

Add validation for missing, blank, and non-scalar provider user IDs and cover the rejection cases with feature tests.
This commit is contained in:
Andras Bacsai 2026-08-18 15:34:37 +02:00
parent f9f26c547c
commit d29139f4a3
2 changed files with 35 additions and 1 deletions

View file

@ -36,7 +36,11 @@ public function login(string $provider, object $oauthUser, OauthSetting $oauthSe
private function resolveOauthUser(object $oauthUser, OauthSetting $oauthSetting, string $email): User
{
$provider = $oauthSetting->provider;
$providerUserId = (string) $oauthUser->id;
$providerUserId = $oauthUser->id ?? null;
if (! is_scalar($providerUserId) || trim((string) $providerUserId) === '') {
throw new HttpException(403, 'OAuth provider did not return a valid user ID');
}
$providerUserId = (string) $providerUserId;
$rawClaims = is_array($oauthUser->user ?? null) ? $oauthUser->user : [];
return DB::transaction(function () use ($oauthUser, $oauthSetting, $email, $provider, $providerUserId, $rawClaims) {

View file

@ -4,9 +4,11 @@
use App\Models\OauthIdentity;
use App\Models\OauthSetting;
use App\Models\User;
use App\Services\Auth\OauthLoginService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Once;
use Laravel\Socialite\Facades\Socialite;
use Symfony\Component\HttpKernel\Exception\HttpException;
uses(RefreshDatabase::class);
@ -121,3 +123,31 @@
'malformed email' => ['not-an-email'],
'missing domain' => ['user@'],
]);
it('rejects oauth logins when the provider does not return a valid user id', function (mixed $invalidId) {
$oauthUser = (object) [
'email' => 'user@example.edu',
'name' => 'Example User',
];
if ($invalidId !== 'missing') {
$oauthUser->id = $invalidId;
}
try {
app(OauthLoginService::class)->login('google', $oauthUser, OauthSetting::where('provider', 'google')->firstOrFail());
} catch (HttpException $exception) {
expect($exception->getStatusCode())->toBe(403)
->and(OauthIdentity::count())->toBe(0)
->and(User::count())->toBe(0);
return;
}
$this->fail('Expected an invalid OAuth provider user ID to be rejected.');
})->with([
'null id' => [null],
'missing id' => ['missing'],
'blank id' => [' '],
'non-scalar id' => [[]],
]);