SEC2-084: shipped() lets a catalogue key override the build's languageTag and direction #39
Labels
No labels
bug
documentation
enhancement
performance
security
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Postulo/postulo-chromium#39
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?
Found on 2026-10-16 in a read-only security review of
postulo-chromiumatb6c1009, checked by a second, independent pass.Severity: Informational · Category: Input Validation · Reference: CWE-20 (Improper Input Validation); OWASP A05:2021 (Security Misconfiguration)
Location:
scripts/build.mjs:33-39src/lib/i18n.js:31-33, 70-72(where the values are used:Accept-Language,documentElement.lang/dir, everytoLocale…call)Issue
The comment above it explains that these two values were moved out of the catalogues precisely
because "a translator, or machine translation, could 'translate'
ltr". The spread puts thecatalogue last, so a catalogue that carries either key wins over the build. No catalogue in
src/_localescarries them today (0 of 40), and Weblate offers translators only the keysenhas, so this is latent. If one came back (a catalogue imported by hand, or
enregaining thekey), the value would feed
Accept-Language,lang/dir, andtoLocaleDateString(tag), whichthrows on a tag that is not one and would stop the popup from drawing.
Impact
None today; a one-line trap for the next person who touches the catalogues.
Fix
Spread first, set after:
{ ...catalogue, languageTag: {...}, direction: {...} }.Done when
test/locales.test.mjshas a case where the catalogue carrieslanguageTag: { message: "nonsense" }and the shipped one still sayslanguage.tag.Related
#10–#13 (closed) are the language roll-out and do not cover the override.