Stored injection through the date fields
- What
- Values held in
state.dateOverridesandstate.targetDatesreach the screen unescaped. They pass through the date formatters into the Progress tab and into the exported File, and are inserted as raw markup. An<img src=x onerror=…>becomes a live element in the document and runs in a real browser. - Vector
- A hostile imported backup. The import warns that it replaces existing data, but it does not validate these two objects key by key. It only checks that each one is an object. The normal path through the interface is safe, because there the value comes from a date input.
- Reproduce
- Import a backup containing
{"dateOverrides":{"dosar":""><img src=x onerror=window.__pwn=1>"}}, then open Progress and export the File. - Expected
- Date values escaped on render, the way every other user-supplied field already is. They were not.
- Proof
tests/qa_securitate.mjs, case S-14, reporting true on both render sites.- Severity
- S2 rather than S1. It needs a backup the user imports deliberately, so there is no anonymous third party in the chain. It is still a real escaping hole, in the same family as the ones already closed.
Fixed in v236
Two fixes were available. Escaping at render would have closed the two sites the test found. Validating at the boundary instead makes migrate() discard anything in those objects that is not a YYYY-MM-DD date, which makes the sentence “these objects only ever hold dates” true of the whole program.
I took the second one. It covers every render site, including the ones nobody had looked at, and the legitimate path is untouched because a date input can only produce that shape. Case S-14 stopped reproducing on both sites.



























