Achtundvierzig. Bei dieser Patch-Nummer ist Symfony 6.4 diese Woche angekommen, und ich hätte gern, dass jeder Laravel-Lead diese Zahl einen Moment lang auf sich wirken lässt. Achtundvierzig Mal ist jemand in einen Long-Term-Support-Branch gegangen, hat einen Fehler gefunden, ihn behoben und getaggt. Die meisten von uns haben sich keinen einzigen dieser Tags angesehen. Ich finde, das muss sich ändern. Wenn deine App auf Laravel läuft, liegt ein guter Teil des Codes, der deine Requests und deine Artisan-Commands abwickelt, unter vendor/symfony, und das Changelog für dieses Verzeichnis gehört auf deine Leseliste, direkt neben das von Laravel.

Der Fall dieser Woche ist so konkret, wie es nur geht. Für die Yaml-Komponente und für HttpFoundation sind Sicherheitsfixes erschienen. Wegen HttpFoundation würde ich schlecht schlafen. Jedes Request-Objekt, das deine Controller bekommen, ist ein Symfony-Request in Laravel-Jacke, also ist eine Lücke dort eine Lücke in deiner App, egal ob in deinem Team dieses Jahr schon mal jemand das Wort Symfony getippt hat. Die Patches sind auf vier gepflegten Branches erschienen, was großzügig von den Maintainern ist und gleichzeitig ein höflicher Hinweis darauf, dass sich niemand damit herausreden kann, seine Version sei zu alt gewesen.

Ich will der Gegenseite gerecht werden, denn das Argument ist echt. In deiner composer.json taucht symfony/http-foundation wahrscheinlich gar nicht auf. Laravel legt den Constraint fest, deine Lock-Datei pinnt die exakte Version, und jedes Mal composer update auszuführen, wenn ein Symfony-Blogpost erscheint, klingt nach einem schnellen Weg, sich an einem Freitagnachmittag ungeprüfte Änderungen einzufangen. Manche Teams haben sich genau so schon die Finger verbrannt, und ihre Vorsicht kommt aus diesen Narben. Die Auswahl dem Framework-Hersteller zu überlassen, ist für ein Team von drei Leuten eine vernünftige Arbeitsteilung.

Warum ich trotzdem auf der anderen Seite lande: Patch-Releases innerhalb einer Symfony-Minor-Linie unterliegen einem strengen Versprechen zur Abwärtskompatibilität, das Risiko eines Updates innerhalb des Bereichs, den Laravel ohnehin erlaubt, ist also gering, und dank der Lock-Datei kannst du genau nachvollziehen, welche Pakete sich bewegt haben, bevor irgendetwas in Produktion geht. Teuer ist das Warten. Laravels Constraint erlaubt die gefixte Version längst; zwischen deinen Servern und dem Patch steht nur, dass niemand den Befehl ausgeführt hat. Ein Security Advisory, das drei Wochen ungepatcht herumliegt, weil das Team auf ein Signal gewartet hat, das nie kommen sollte, ist genau der Weg, auf dem aus gewöhnlichen Bugs Incident-Reports werden.

Die Fixes ohne Sicherheitsbezug zeigen dasselbe, nur leiser. Einer davon hat eine Drift in der Clock-Komponente rund um die Zeitumstellung korrigiert. Das klingt nach Trivia, bis dir einfällt, dass ein Großteil Europas in etwa einer Woche, am 25. Oktober, die Uhren zurückstellt und irgendwo ein geplanter Job gleich zweimal um 02:30 losläuft, oder gar nicht. Ein anderer Fix hat geklärt, wie BrowserKit Cookie-Pfade liest, also genau die Sorte Problem, durch die ein Integrationstest bei einem Entwickler wackelt und bei allen anderen grün ist. Nichts davon wird in einer Laravel-Release-Note auftauchen, denn aus Laravels Sicht hat sich nichts geändert.

Meine praktische Haltung sieht deshalb so aus. Abonnier den Feed des Symfony-Blogs oder zumindest die Security Advisories. Lass composer audit in der CI laufen, damit eine bekannte Schwachstelle einen Build scheitern lässt, statt darauf zu warten, dass ein Mensch sie bemerkt. Und wenn eine Patch-Runde rauskommt, führ auf einem Branch gezielt composer update symfony/* aus, lies den Lock-Diff, lass die Testsuite darauf herumkauen, merge. In einem gesunden Projekt sind das zwanzig Minuten, und die meiste Zeit davon wartest du auf PHPUnit. Go-Entwickler witzeln gern, ihre Standardbibliothek sei ihr Framework; wir bekommen etwas Ähnliches geschenkt, gepflegt von Leuten, die Fixes auf eine 6.4-Linie zurückportieren, die die meisten Hersteller längst aufgegeben hätten.

Dahinter steckt auch ein kleiner kultureller Punkt. Laravel und Symfony werden an Konferenz-Bars gern als Rivalen dargestellt, und die composer.lock widerspricht dem ganz leise. Die Arbeit, die das eine stabil hält, hält auch das andere stabil, und wer Upstream-Wartung als Nachrichten von jemand anderem abtut, übersieht die Hälfte dessen, was deine Nutzer schützt. Zu wissen, woher deine Request-Klasse kommt, ist kein Verrat an deinem Framework. Es ist einfach korrekt.

Was ich wirklich gern von dir hören würde: Wie geht dein Team heute mit Upstream-Patches um? Aktualisiert ihr Symfony-Komponenten in deren eigenem Takt, etwa mit Renovate oder Dependabot, oder wartet ihr, bis ein Laravel-Release sie mitbringt, und hat dich eine der beiden Entscheidungen schon mal in Produktion erwischt?