fix(security): drop image-size via metro 0.83.8 overrides #114
No reviewers
Labels
No labels
autopilot:pending-human
source:analyste
source:defenseur
source:human
source:medic
status:approved
status:blocked
status:in-progress
status:needs-clarification
status:needs-fix
status:ready
status:review
status:triage
type:bug
type:feature
type:infra
type:refactor
type:schema
type:security
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: maximus/simpl-liste#114
Loading…
Reference in a new issue
No description provided.
Delete branch "issue-108-metro-0.83.8"
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?
Lève la seule racine non corrigeable de l'arbre de dépendances, suivie dans #108.
Ce qui a débloqué la situation
#108 attendait qu'
image-sizepublie une version saine. Ce n'est toujours pas arrivé — vérifié à la source (api.github.com/advisories) :first_patched_version<= 2.0.2<= 2.0.2image-size@2.0.2(2025-04-02) reste la dernière publiée. Sur ce point, l'analyse de #108 tient toujours : aucun override d'image-sizen'a de cible saine.Le déblocage vient d'ailleurs : metro a retiré la dépendance au lieu d'attendre le correctif upstream, et l'a backporté sur la ligne de maintenance
0.83.xle 2026-08-19 — sept jours après la dernière ré-évaluation de #108.Diff de dépendances
0.83.7 → 0.83.8: une seule suppression,image-size, zéro ajout.Metro a vendoré le calcul de dimensions dans
src/lib/imageSize.js(« derived from image-size's format support, reduced »). Le code vendoré ne gère quebmp, gif, jpeg, ktx, png, psd, svg, tiff, webp— aucun parseur ICNS, JXL ni HEIF, soit exactement les trois visés par les advisories. La vulnérabilité disparaît par construction, pas par renommage.metro@0.83.3étant le seul demandeur d'image-sizedans tout l'arbre, les findings HIGH transitifs s'effondrent avec elle.Pourquoi un override
@expo/metro@54.2.0épingle les 14 paquets metro en version exacte0.83.3—npm updatene peut rien. Les 14 sont déplacés ensemble pour éviter un arbre metro panaché (metro 0.83.8 cohabitant avec desmetro-*en 0.83.3). L'overridewsexistant est préservé via la clé".":Vérifications
npm auditimage-sizedans l'arbrenode_modules)npm install+ postinstallreact-native-android-widget@0.21.0✔npm testnpx expo export --platform androidimage-sizeenginesde metro 0.83.8 :node >=20.19.4, identique à 0.83.3 — aucun relèvement de plancher. EAS installe depuis le lockfile, l'override est honoré en build.Hors périmètre
La HIGH résiduelle est
browserslist(croissance mémoire non bornée + écriture de prototype viabrowserslist-stats.json). Elle préexiste sur master, sans lien avec #108, et n'est couverte par aucune issue ouverte. Les 9 moderate et 1 low sont inchangés — aucune régression.Closes #108
🤖 Generated with Claude Code
https://claude.ai/code/session_016Y4GzEsmDryrwtQcmBNw9P
Verdict : APPROVE
Chaque affirmation du corps de la PR a été reproduite indépendamment — audit, arbre de dépendances, lockfile, tests, export et serveur de dev (surface que le corps ne couvrait pas). La seule régression trouvée, trois points d'entrée
@expo/metroqui ne résolvent plus, n'a aucun consommateur dans l'arbre : latente, non bloquante.Vérifié à la source
image-sizeabsentjqsur le lock +ls node_modulesmasterrejoué en scratchpadnode_modules/metro requires image-size ^1.0.2— uniquemetro/src/lib/imageSize.jsbmp, gif, jpeg, jpg, ktx, png, psd, svg, tiff, webp— les 3 formats visés par les advisories sont absentsmaster(baseline)npm audit --package-lock-onlysur le lock de masternpm auditimage-size.viades advisories mastermetro,metro-config,metro-transform-worker,@expo/metro,@expo/metro-config,@expo/cli,expo— tousvia image-sizebrowserslistseul, présent aussi sur masterjqsur le lockob1en 0.83.8, un exemplaire chacun, aucun 0.83.3 résolunpm ls metrooverridden, aucuninvalidwspréservépackage.jsonde metrometro/node_modules/ws → 7.5.11, et metro 0.83.8 déclare toujoursws ^7.5.10— pas de saut majeurenginesinchangénode >=20.19.4des deux côtéspackage.jsonnpm cid'EAS honore bien l'overridenpm testreact-native-android-widget@0.21.0 ✔expo export --platform androidexpo startsur port dédié (8391, vérifié libre, PID de l'écouteur confirmé) +curl /index.bundleresolvedsurregistry.npmjs.orgLa preuve par mutation prend ici la forme inverse de l'habituelle : rejouer le lock de
masterfait remonter les 8 findings enracinées dansimage-size(9 HIGH au total), le lock de la PR n'en laisse qu'une. Le finding était réel et il disparaît par construction.Finding — trois points d'entrée
@expo/metrone résolvent plus (non bloquant)@expo/metro@54.2.0est un pur jeu de ré-exports écrit contre 0.83.3. Trois de ses fichiers visent des chemins privés que metro a déplacés ou supprimés entre 0.83.3 et 0.83.8 :@expo/metrometro-resolver/utils/toPosixPathmetro-resolver/private/utils/toPosixPathmetro-file-map/lib/dependencyExtractormetro-file-map/private/lib/dependencyExtractorsrc/plugins/dependencies/metro/node-haste/Packagemetro/private/node-haste/PackagePackageCachesubsiste)Les trois lèvent
MODULE_NOT_FOUNDà l'exécution sur la branche (vérifié parrequiredirect).Ce qui les rend non bloquants : aucun paquet de l'arbre ne les requiert. Grep exhaustif sur tout
node_modules, tous types de fichiers, à la fois sur la forme@expo/metro/<sous-chemin>et sur le spécificateur numetro-*/private/...— les seuls fichiers qui les mentionnent sont les shims eux-mêmes.@expo/cliimporte bien@expo/metro/metro-resolver, mais le shim racine, qui résout ; jamais le sous-cheminutils/toPosixPath. Sur les 206 imports profondsmetro*/private/...présents dans l'arbre, 203 résolvent — ces 3 sont les seuls cassés, et ils sont morts.Note méthodologique :
private/*est un alias de la tableexportsverssrc/*.js. Un premier passage qui cherchait un répertoireprivate/littéral dans les tarballs a conclu « absent des deux côtés », donc « préexistant » — faux. C'est la résolution via la tableexportsqui donne le vrai delta 0.83.3 → 0.83.8.Ce que ça dit quand même : 0.83.3 → 0.83.8 n'est pas un bump de patch pur côté API privée, malgré le numéro de version. Le risque résiduel est qu'un futur patch d'
expo/@expo/clise mette à charger un de ces sous-chemins. Une ligne dans #108 ou dansSTATE.mdéviterait que ce soit une énigme dans six mois.Notes, aucune action requise
Écart
hermes-parserélargi. metro passe de 0.32.0 à 0.35.0 pendant que@react-native/codegen,@expo/metro-configetbabel-plugin-syntax-hermes-parserrestent sur 0.29.1. L'écart préexiste sur master (0.32 contre 0.29) — la PR l'élargit sans le créer. L'AST produit parmetro-babel-transformertraverse ensuite le preset Babel de RN 0.81 ; export et serveur de dev sortent tous deux un bundle valide sur 4624 modules, ce qui couvre la syntaxe réelle du projet.chalkdisparaît aussi des dépendances de metro entre 0.83.3 et 0.83.8. Le corps ne mentionne qu'image-sizeparce qu'il compare 0.83.7 → 0.83.8 ; sur 0.83.3 → 0.83.8 le retrait est double. Sans effet.^0.83.8autorise la dérive jusqu'à<0.84.0. Le lock est commité et EAS installe parnpm ci: pas de risque pratique, et c'est cohérent avec le style des overrides déjà en place.Mot-clé de fermeture. Le commit porte
Refs #108, le corps de la PR porteCloses #108. Forgejo lit les deux au merge, donc #108 se fermera bien par le corps. Simple asymétrie, rien à corriger.🤖 Review générée par
/pr-review