Recovery-service crash bij opstarten (StackOverflowError uit jsonDecode niet gevangen) #1359
Labels
No labels
accepted
bug
declined
docs
duplicate
enhancement
good first issue
in-progress
needs-info
privacy
security
triage
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
LibreKAT/Ocideck#1359
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Bevinding
RecoveryService.loadAll(lib/services/recovery_service.dart:257) loopt bijhet opstarten van de app en doet
jsonDecodeop elk.json-bestand in derecovery-map. Er is een try/catch per bestand, wat een gewone
FormatExceptionvangt.Maar een
StackOverflowErroruit een diep-geneste JSON wordt in Dart nietdoor try/catch gevangen — het is een
Errordie de isolate kan meenemen. Eencorrupt herstelbestand (bv. na een crash tijdens het schrijven) met diepe
nesting zou de app bij het opstarten laten crashen, en de gebruiker kan er
niet eens omheen — de recovery-service draait vóór de UI.
Waarom dit kritieker is dan #1353
#1353 gaat over
jsonDecodeop sidecars en grafiekdata bij het openen van eenbestand — de gebruiker moet een bestand openen om het te triggeren.
Dit is een subset van #1353, maar op een extra kritieke call-site: de
recovery-service draait bij het opstarten van de app, vóór de UI, en leest
elk
.json-bestand in de recovery-map. Een corrupt herstelbestand laat deapp niet meer opstarten, en de gebruiker kan er niet omheen — hij kan niet
eens bij de instellingen om de recovery-map leeg te maken.
Hoe een corrupt herstelbestand ontstaat
laat normaal een
.tmpachter, maar een crash op het juiste moment kan eenhalf geschreven
.jsonopleveren).voor een lokaal-eerst app, maar niet nul).
Oplossingsrichting
Dit is een call-site van #1353: een depth-guarded JSON-parser (of pre-scan)
op de recovery-service lost het op. Maar omdat dit het opstart-pad is, verdient
het een extra verdediging: als de recovery-service ondanks de diepte-check
toch faalt, moet de app nog steeds opstarten — de recovery is een
gemaksfunctie, geen voorwaarde om te kunnen werken.
Twee lagen:
nesting-diepte vóór
jsonDecode, weiger boven een redelijke grens.loadAllondanks de diepte-check faalt,de recovery-map hernoemen naar een backup-naam (niet verwijderen — de
gebruiker wil misschien iets terughalen) en de app normaal laten opstarten
met een lege recovery-lijst.
Inschatting: ~10-15 regels voor de fallback, bovenop de gedeelde oplossing
met #1353.
Herkomst
Gevonden tijdens security research naar defense-in-depth voor OciDeck. #1353
identificeerde de JSON-diepte-limiet; dit is de call-site waar het
kritiek wordt — niet "een bestand kan niet openen" maar "de app start niet
meer op".