fix: Rechteausweitung ueber Rollenzuweisung und weitere Auth-Haertung
Ein Sicherheitsaudit deckte auf, dass jede Rolle mit users:update sich selbst per PATCH /users/:id auf eine Admin-Rolle heraufstufen konnte, da roleId ohne eigene Berechtigung und ohne Selbstbezug-Pruefung akzeptiert wurde. Ausserdem lag ein fest im Code hinterlegtes Standard-Admin-Passwort vor, das bei fehlender SEED_ADMIN_PASSWORD-Env greift. - Neue Berechtigung users:assign-role, getrennt von users:create/update, fuer jede Rollenzuweisung erforderlich - Selbstaenderung der eigenen Rolle serverseitig blockiert (auch fuer Admins), ebenso Selbst-Reset der eigenen MFA ueber die Admin-Route - Seed erzeugt bei fehlender Env ein zufaelliges statt eines fixen Passworts - Wiederverwendung eines bereits rotierten Refresh-Tokens (Diebstahl- Indiz) widerruft nun alle Sessions des betroffenen Nutzers - Rate-Limit auf MFA-Enrollment-Bestaetigung ergaenzt Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
1 parent
7bd2a3dc3a
commit
1b16b49913
7 files changed
+146
-7
No files matched your search
@@ -207,7 +207,25 @@ export class AuthService {
|
||||
const stored = await this.prisma.refreshToken.findUnique({
|
||||
where: { tokenHash },
|
||||
});
|
||||
if (!stored || stored.revokedAt || stored.expiresAt < new Date()) {
|
||||
if (!stored) {
|
||||
throw new UnauthorizedException('Invalid refresh token');
|
||||
}
|
||||
if (stored.revokedAt) {
|
||||
// Reuse of an already-rotated-out refresh token is a strong signal
|
||||
// it was stolen (a legitimate client only ever presents the newest
|
||||
// token) - revoke every other active session for this user rather
|
||||
// than trusting rotation alone to have contained the leak.
|
||||
await this.prisma.refreshToken.updateMany({
|
||||
where: { userId: stored.userId, revokedAt: null },
|
||||
data: { revokedAt: new Date() },
|
||||
});
|
||||
this.permissionResolver.invalidateUser(stored.userId);
|
||||
this.logger.warn(
|
||||
`Refresh token reuse detected for user ${stored.userId}; all sessions revoked`,
|
||||
);
|
||||
throw new UnauthorizedException('Invalid refresh token');
|
||||
}
|
||||
if (stored.expiresAt < new Date()) {
|
||||
throw new UnauthorizedException('Invalid refresh token');
|
||||
}
|
||||
const user = await this.usersService.findById(stored.userId);
|
||||
|
||||
Reference in new issue
Block a user