security: Breadcrumbs ohne Daten an GlitchTip, Übergangsmarke der Session-Sperre entfernt

- ErrorReportScrubber entfernt die Daten aller Breadcrumbs und bereinigt ihre
  Nachrichten; Livewire-Breadcrumbs standardmäßig aus — das SDK hängt dort
  Formularwerte und Properties an (Roadmap 4.9). Bestand in GlitchTip geprüft:
  keine Formular- oder Passwortdaten.
- SessionRevocation::legacyCachedMark() entfernt (Übergang bis v1.6.0)

Changelog: Sicherheit

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-10-09 13:35:54 +00:00
parent 29e68330ca
commit d1b9ffdcf1
6 changed files with 49 additions and 18 deletions

View file

@ -5,7 +5,6 @@ namespace App\Services\Auth;
use App\Models\User;
use Illuminate\Auth\Events\Login;
use Illuminate\Contracts\Session\Session;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;
/**
@ -90,7 +89,7 @@ class SessionRevocation
*/
public function isRevoked(User $user, Session $session): bool
{
$revokedAt = max((int) $user->sessions_revoked_at_ms, $this->legacyCachedMark((int) $user->getKey()));
$revokedAt = (int) $user->sessions_revoked_at_ms;
if ($revokedAt === 0) {
return false;
@ -98,14 +97,4 @@ class SessionRevocation
return (int) $session->get(self::SESSION_KEY, 0) < $revokedAt;
}
/**
* Übergang: Bis v1.5.0 lag die Marke nur im Cache, mit Ablauf nach
* `session.lifetime` + 5 Minuten. Sperren aus dieser Zeit sollen über den
* Deploy hinweg gelten. Kann im Release nach v1.6.0 entfallen.
*/
private function legacyCachedMark(int $userId): int
{
return (int) Cache::get('auth.sessions-revoked-at.'.$userId, 0);
}
}

View file

@ -4,6 +4,7 @@ namespace App\Support\Monitoring;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;
use Sentry\Breadcrumb;
use Sentry\Event;
use Sentry\EventHint;
use Sentry\UserDataBag;
@ -41,6 +42,8 @@ class ErrorReportScrubber
$event->setUser($userId !== null ? UserDataBag::createFromUserIdentifier($userId) : null);
$event->setRequest(self::scrubRequest($event->getRequest()));
$event->setBreadcrumb(array_map(self::scrubBreadcrumb(...), $event->getBreadcrumbs()));
foreach ($event->getExceptions() as $exception) {
$exception->setValue(self::scrubText($exception->getValue()));
}
@ -58,6 +61,20 @@ class ErrorReportScrubber
return $event;
}
public static function scrubBreadcrumb(Breadcrumb $breadcrumb): Breadcrumb
{
$message = $breadcrumb->getMessage();
return new Breadcrumb(
$breadcrumb->getLevel(),
$breadcrumb->getType(),
$breadcrumb->getCategory(),
$message !== null ? self::scrubText($message) : null,
[],
$breadcrumb->getTimestamp(),
);
}
/**
* @param array<string, mixed> $request
* @return array<string, mixed>