Bug #339
offen[Bugsink] DateMalformedStringException: Failed to parse time string (-1 OR 5*5=26 -- -01-01) at position 6 (5): Unexpected character
0%
Beschreibung
Bugsink: https://bugsink.cytrus.de/issues/issue/246f0a12-f301-420e-9c27-3ef7d1fd5595/event/last/
Typ: NEW issue
Projekt: www-rietberg-de
Bugsink Alert
DateMalformedStringException: Failed to parse time string (-1 OR 5*5=26 -- -01-01) at position 6 (5): Unexpected character
Automatisch erstellt durch n8n
KI-Analyse:
1. Ursache identifizieren
Der DateMalformedStringException entsteht, weil ein nicht‑validierter String (hier -1 OR 5*5=26 -- -01-01) direkt an den PHP‑DateTime‑Konstruktor (oder an strtotime()/new \DateTimeImmutable()) übergeben wird.
Der String beginnt mit -1 – beim Versuch, ihn als ISO‑8601‑Datum zu parsen, stößt der Parser beim 6. Zeichen (5) auf ein unerwartetes Zeichen und wirft die Ausnahme.
Der Stack‑Trace zeigt, dass die Ausnahme nachdem die üblichen TYPO3‑Middleware‑Schichten (VerifyHostHeader, NormalizedParamsAttribute, ResponsePropagation) durchlaufen wurden, im Kern‑HTTP‑Dispatch‑Fluss auftritt. Das bedeutet: Der fehlerhafte Code liegt nicht im TYPO3‑Core, sondern in einer Extension bzw. im eigenen Projektcode, der einen GET/POST‑Parameter (vermutlich ein Datums‑Filter) ungeprüft an einen Datum‑Parser übergibt.
Typische Stellen, an denen so etwas passiert:
| Ort | Beschreibung |
|---|---|
| Controller‑Action eines Plugins (z. B. List‑View) | Ein Parameter wie ?tx_news_pi1[date]=… wird aus $_GET bzw. $request->getQueryParams() genommen und direkt mit new \DateTime($value) verarbeitet. |
| ViewHelper oder DataProcessor | Beim Berechnen von Datumsbereichen für eine Ausgabe wird ein Fluid‑Parameter ohne Prüfung an strtotime() übergeben. |
| Eigene Middleware / EventListener | Manche Entwickler binden eigenen Code an typo3/cms-core/Classes/Http/MiddlewareDispatcher.php ein und prüfen dort Parameter – dort kann das gleiche Problem auftreten. |
2. Fix beschreiben (konkret)
Schritt‑für‑Schritt‑Lösung
-
Eingangsdaten validieren – bevor ein String an
DateTime/DateTimeImmutableübergeben wird, muss geprüft werden, dass er das erwartete Datumsformat aufweist.$raw = $request->getQueryParam('date'); // Beispielparameter if ($raw === null) { // kein Datum angegeben → Standardwert verwenden oder Fehler zurückgeben $dateTime = new \DateTimeImmutable('today'); } else { // Erwartetes Format: YYYY‑MM‑DD (oder YYYY‑MM‑DD HH:MM:SS) $format = 'Y-m-d'; // bei Bedarf auch 'Y-m-d H:i:s' $dateTime = DateTimeImmutable::createFromFormat($format, $raw); if ($dateTime === false || $dateTime->format($format) !== $raw) { // Ungültiges Datum → entsprechende Reaktion (400, Standardwert, Log‑Eintrag) throw new \InvalidArgumentException( sprintf('Invalid date format "%s", expected "%s"', $raw, $format), 1629874563 ); } } -
Alternativ: Verwende TYPO3‑Hilfsklassen – TYPO3 stellt seit v10 die Klasse
\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstanceDateTime()nicht direkt, dafür aber das empfohlene Vorgehen überDateTimeImmutable::createFromFormat()(wie oben). Für reine Ausgabe kann\TYPO3\CMS\Core\Utility\GeneralUtility::date()genutzt werden, nicht zum Parsen. -
Error‑Handling anpassen – statt die rohe Exception nach oben bubbeln zu lassen, sollte sie gefangen und entweder ein passender HTTP‑Status (400 Bad Request) zurückgegeben oder ein Fallback‑Datum verwendet werden. Damit wird die Seite weiterhin nutzbar und der Angreifer erhält keine detaillierten Fehlermeldungen (Information Disclosure verhindern).
-
Unit‑Test hinzufügen – um zukünftige Regressionen zu vermeiden, einen Test schreiben, der sowohl gültige als auch bewusst falsche (z. B. SQL‑Injection‑Strings) Eingaben prüft.
3. Betroffene TYPO3‑Extension nennen
Der Stack‑Trace enthält keinerlei Extension‑spezifische Klassen, weshalb die genaue Extension aus dem Trace nicht hervorgeht. Allerdings ist das beschriebene Szenario sehr typisch für Extensions, die Datums‑Filter in List‑Views anbieten, insbesondere:
| Extension | Warum sie betroffen sein kann |
|---|---|
| tx_news (EXT:news) | besitzt ein Datums‑Filter‑Feld (date) in der List‑View, das über GET‑Parameter ausgelesen und in einem DateTime‑Objekt verarbeitet wird. |
| tx_sr_feuser_register | hat ein Geburtsdatum‑Feld, das in manchen Frontend‑Plugins ähnlich geparsed wird. |
| tx_calendar / tx_shevents | ebenfalls Datums‑Filter für Veranstaltungen. |
| Eine eigene oder individuelle Extension | Jeder selbstgeschriebene Plugin‑Code, der GET/POST‑Parameter wie date, from, to usw. ohne Validierung an new \DateTime() übergibt, führt zu genau diesem Fehler. |
Da der Fehler bereits in der Middleware‑Kette auftritt, nachdem die üblichen Host‑Header‑ und Parameter‑Normalisierungs‑Middleware durchgelaufen ist, liegt die Vermutung nahe, dass es sich um ein Frontend‑Plugin handelt, das im Haupt‑Request (nicht im Backend) ausgeführt wird – also sehr wahrscheinlich eine öffentliche Extension wie news oder ein eigenes Frontend‑Plugin.
4. Confidence (0‑100 %)
- Analyse der Ausnahme: 100 % sicher – es handelt sich eindeutig um ein fehlerhaftes Datum‑Parsing.
- Zuordnung zum Code‑Ort (Middleware‑Stack): 90 % sicher – die Ausnahme wird nachdem die Kern‑Middleware abgearbeitet wurde geworfen, also definitiv im Anwendungs‑ bzw. Extension‑Code.
- Spezifische Extension: 70 % sicher – aufgrund der genannten Häufigkeit und des typischen Einsatzes von Datumsfiltern lässt sich news als wahrscheinlichste Vermutung nennen, jedoch kann ohne direkten Stack‑Frame aus der Extension keine absolute Sicherheit gegeben werden.
Gesamt‑Confidence: ≈ 80 % (Ursache und Fix sind klar; die genaue Extension ist wahrscheinlich, aber nicht 100 % belegt).
Kurzfassung zum sofortigen Einsatz¶
// Beispiel: In einer Controller-Action eines Plugins
public function listAction(ServerRequestInterface $request): ResponseInterface
{
$dateParam = $request->getQueryParam('date');
if ($dateParam !== null) {
$date = DateTimeImmutable::createFromFormat('Y-m-d', $dateParam);
if ($date === false || $date->format('Y-m-d') !== $dateParam) {
throw new \BadRequestException('Invalid date supplied');
}
} else {
$date = new \DateTimeImmutable('today');
}
// Weiterverwendung von $date …
…
}
Durch konsequente Validierung (oder Nutzung von DateTimeImmutable::createFromFormat()) lässt sich der DateMalformedStringException zukünftig vermeiden und gleichzeitig die häufig genutzte Angriffssurface (Datum‑Parameter → möglicher SQL‑Injection‑Vektor) schließen.
Nichts anzuzeigen