fix(kiosk): escape data-derived strings in innerHTML (RG-T15) #20

Merged
Corentin merged 1 commit from fix/p3-kiosk-escape-xss into dev 2026-06-16 14:20:52 +02:00
Owner

RG-T15 (echappement sortie anti-XSS) — borne

docs/merise/mlt.md (RG-T15) impose que toute chaine derivee des donnees du catalogue rendue en HTML cote borne soit echappee (textContent ou echappeur explicite, pas innerHTML brut). Seul page-product-menu.js definissait et appliquait escHtml() ; les 3 autres scripts de rendu injectaient product.nom / item.libelle / product.image directement dans innerHTML sans echappement.

Sink le plus net : src="${product.image}" (une valeur image type x" onerror="..." casse hors de l'attribut).

Correctif

  • escHtml() centralise et exporte depuis state.js (source unique, deja importee par les modules de page) au lieu d'etre duplique localement.
  • Echappement applique aux champs data-derived dans page-products.js, page-product.js, page-cart.js : texte visible + attributs src/alt/aria-label des templates innerHTML, plus les 4 libelle du bloc composition menu.
  • Laisses inchanges (pas des sinks HTML) : document.title = ... (assignation de texte) et el.setAttribute('aria-label', ...) (pas de parsing HTML).

Portee

Donnees statiques aujourd'hui (data/*.json ecrites par le dev) -> pas exploitable maintenant. Mais data.js documente le bascule P4 vers /api/products : ces memes champs deviendront des valeurs CRUD admin en base. Le CRUD produits admin etant deja merge (#17), cet echappement ferme une XSS stockee latente sur borne avant que l'API ne la rende vivante.

Validation : syntaxe ES module OK (node --check) sur les 4 fichiers ; aucune injection innerHTML data-derived non echappee restante. Pas de label auto-merge : relecture manuelle.

## RG-T15 (echappement sortie anti-XSS) — borne `docs/merise/mlt.md` (RG-T15) impose que toute chaine derivee des donnees du catalogue rendue en HTML cote borne soit echappee (textContent ou echappeur explicite, pas `innerHTML` brut). Seul `page-product-menu.js` definissait et appliquait `escHtml()` ; les 3 autres scripts de rendu injectaient `product.nom` / `item.libelle` / `product.image` directement dans `innerHTML` sans echappement. Sink le plus net : `src="${product.image}"` (une valeur image type `x" onerror="..."` casse hors de l'attribut). ## Correctif - `escHtml()` centralise et **exporte depuis `state.js`** (source unique, deja importee par les modules de page) au lieu d'etre duplique localement. - Echappement applique aux champs data-derived dans `page-products.js`, `page-product.js`, `page-cart.js` : texte visible + attributs `src`/`alt`/`aria-label` des templates `innerHTML`, plus les 4 `libelle` du bloc composition menu. - Laisses inchanges (pas des sinks HTML) : `document.title = ...` (assignation de texte) et `el.setAttribute('aria-label', ...)` (pas de parsing HTML). ## Portee Donnees statiques aujourd'hui (`data/*.json` ecrites par le dev) -> pas exploitable maintenant. Mais `data.js` documente le bascule **P4 vers `/api/products`** : ces memes champs deviendront des valeurs CRUD admin en base. Le CRUD produits admin etant deja merge (#17), cet echappement ferme une XSS stockee latente sur borne avant que l'API ne la rende vivante. Validation : syntaxe ES module OK (`node --check`) sur les 4 fichiers ; aucune injection `innerHTML` data-derived non echappee restante. Pas de label `auto-merge` : relecture manuelle.
Corentin added 1 commit 2026-06-16 12:31:49 +02:00
fix(kiosk): escape data-derived strings injected into innerHTML (RG-T15)
All checks were successful
CI / secret-scan (pull_request) Successful in 7s
CI / php-lint (pull_request) Successful in 20s
CI / static-tests (push) Successful in 32s
CI / static-tests (pull_request) Successful in 32s
CI / secret-scan (push) Successful in 9s
CI / php-lint (push) Successful in 19s
CI / auto-merge (pull_request) Successful in 7s
CI / auto-merge (push) Has been skipped
a07bcbe3c8
RG-T15 (mlt.md) impose d'echapper toute valeur de catalogue rendue en HTML
cote borne. Seul page-product-menu.js definissait/appliquait escHtml ; les 3
autres scripts de rendu injectaient product.nom / item.libelle / product.image
directement dans innerHTML sans echappement.

- escHtml centralise et exporte depuis state.js (source unique, importe par les
  modules de page) au lieu d'etre duplique localement.
- Echappement applique aux champs data-derived dans page-products.js,
  page-product.js et page-cart.js (texte + attributs src/alt/aria-label des
  templates innerHTML, dont le sink src="${image}").

Les chemins document.title et setAttribute(...) restent inchanges : ce ne sont
pas des sinks HTML (assignation de texte, pas de parsing).

Donnees statiques aujourd'hui (data/*.json), mais data.js documente le bascule
P4 vers /api/products : ces memes champs deviendront des valeurs CRUD admin en
base, d'ou le risque de XSS stockee sur borne que cet echappement ferme.
Corentin merged commit 9ddb4ccb27 into dev 2026-06-16 14:20:52 +02:00
Corentin deleted branch fix/p3-kiosk-escape-xss 2026-06-16 14:20:52 +02:00
Sign in to join this conversation.
No reviewers
No labels
auto-merge
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: AcadeNice/corentin_wakdo#20
No description provided.