Fix account-takeover: bind users to nextcloud_id, not email
Deploy / deploy (push) Successful in 16s

Matching users by email alone allows an attacker with a self-registered
Nextcloud account to hijack any Filament user. Now we look up by
nextcloud_id first; email is only used when creating a brand-new account,
and nextcloud_id is immediately written to the row so future logins
use the stable Nextcloud user ID.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Malek TellissiandClaude Sonnet 4.6 committed 2026-09-13 02:54:19 +02:00
1 parent 25d9330538
commit 4b99ffea15
3 files changed
+39 -5

No files matched your search

+16 -5
View File
@@ -26,13 +26,24 @@ class OAuthController extends Controller
abort(403, 'Kein Zugriff — bitte einer SMS-Gruppe in Nextcloud beitreten.');
}
$user = User::firstOrCreate(
['email' => $socialUser->getEmail()],
[
$nextcloudId = (string) $socialUser->getId();
$user = User::where('nextcloud_id', $nextcloudId)->first();
if (! $user) {
$user = User::where('email', $socialUser->getEmail())->first();
if (! $user) {
$user = new User([
'name' => $socialUser->getName() ?? $socialUser->getNickname() ?? $socialUser->getEmail(),
'email' => $socialUser->getEmail(),
'password' => Str::random(40),
]
);
]);
}
$user->nextcloud_id = $nextcloudId;
$user->save();
}
$user->syncRoles(array_values($smsRoles));
+1
View File
@@ -22,6 +22,7 @@ class User extends Authenticatable implements FilamentUser
'name',
'email',
'password',
'nextcloud_id',
];
/**
@@ -0,0 +1,22 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::table('users', function (Blueprint $table) {
$table->string('nextcloud_id')->nullable()->unique()->after('email');
});
}
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('nextcloud_id');
});
}
};