• pnpm
  • sicurezza
  • dipendenze
  • npm
  • yarn

Aggiorna le dipendenze transitive con PNPM: Risolvi le vulnerabilità di sicurezza senza rompere nulla

Risolvere le vulnerabilità di sicurezza può essere un compito frustrante, soprattutto quando coinvolge dipendenze transitive. Scopri come aggiornarle senza impattare le tue dipendenze dirette.

Gao
Gao
Founder

Oggigiorno, le vulnerabilità di sicurezza sono un problema comune nello sviluppo software. Fortunatamente, abbiamo strumenti come GitHub Dependabot per aiutarci a mantenere le nostre dipendenze aggiornate con rilevamento automatico e pull request.

Dependabot

Tuttavia, non sempre funziona come previsto. Poiché alcune dipendenze sono transitive, aggiornarle può essere un compito difficile per questi strumenti poiché non sanno l'impatto degli aggiornamenti e quale decisione prendere in caso di conflitti. Dobbiamo gestire questi casi manualmente.

Metodi che non funzionano

  • Comandi ufficiali come pnpm up incasineranno il file pnpm-lock.yaml. C'è un problema a riguardo che è ancora aperto al momento della scrittura.
  • Installare l'ultima versione della dipendenza diretta che ha la dipendenza transitiva obiettivo potrebbe non funzionare. Se la dipendenza diretta non ha aggiornato le definizioni delle versioni, la dipendenza transitiva non verrà aggiornata poiché è stata risolta e bloccata nel file pnpm-lock.yaml.

La soluzione

Il campo overrides è una funzionalità potente in PNPM che ti permette di sovrascrivere alcune risoluzioni di versione. Useremo questa funzionalità per aggiornare le dipendenze transitive e rendere la modifica minima possibile.

Utilizziamo l'avviso di Dependabot di cui sopra come esempio. Ci informa che il pacchetto follow-redirects ha una vulnerabilità di sicurezza e la versione corretta è 1.15.6. Tuttavia, la dipendenza diretta gatsby utilizza axios che dipende da [email protected].

Passo 1: Trova la dipendenza transitiva

Ci sono molti modi per individuare la dipendenza transitiva, ma consiglierei il modo più semplice: cercare nel file pnpm-lock.yaml.

E "pnpm why"?

Il comando pnpm why <package> è sicuramente utile. Tuttavia, potrebbe confonderti in questo caso. Ad esempio, quando eseguo pnpm why follow-redirects, ecco una parte dell'output:

In realtà, c'è solo una risoluzione per follow-redirects nel file pnpm-lock.yaml. Il comando pnpm why potrebbe mostrarti più percorsi che dipendono dalla stessa versione del pacchetto.

Passo 2: Aggiungi le overrides

Il caso più semplice è che esista solo una risoluzione nel file pnpm-lock.yaml. Puoi aggiungere direttamente la sostituzione nel file package.json:

Se sei in un workspace, dovresti aggiungere la sostituzione al file package.json della root del workspace.

Passo 3: Applica le modifiche

Esegui pnpm install per applicare le modifiche. Possiamo vedere che il pacchetto follow-redirects viene aggiornato a 1.15.6 nel file pnpm-lock.yaml con modifiche minime.

Ora puoi rimuovere il campo overrides dal file package.json per mantenerlo pulito. Quindi esegui nuovamente pnpm install per convalidare che le modifiche possono essere applicate senza il campo overrides.

Risoluzione dei problemi

I passaggi precedenti sono il caso ideale. Le cose potrebbero non andare sempre come previsto. Ecco alcuni suggerimenti per risolvere i problemi:

La versione viene ripristinata dopo aver rimosso il campo "overrides"

Ciò può accadere quando il pacchetto dipendente ha una versione fissa o un intervallo che non include la versione target. Controlla il file package.json del pacchetto dipendente, in questo caso axios, per vedere se è applicabile.

Se è così, devi mantenere il campo overrides nel file package.json fino a quando il pacchetto dipendente non aggiornerà le definizioni di versione.

Ci sono più risoluzioni per la dipendenza transitiva

Man mano che il progetto cresce, il file pnpm-lock.yaml potrebbe gonfiarsi con più risoluzioni per lo stesso pacchetto. Ad esempio, potrebbero esserci due versioni principali dello stesso pacchetto foo:

Il report di vulnerabilità mostra che [email protected] ha un problema di sicurezza che è stato risolto in 1.0.1, e [email protected] non è interessato. Non possiamo semplicemente aggiungere una sostituzione a foo:

  • Se aggiungiamo una sovrascrittura "foo": "^1.0.1", il [email protected] verrà retrocesso a 1.0.1. Questo potrebbe interrompere il progetto poiché il [email protected] potrebbe avere alcune nuove funzionalità utilizzate nei pacchetti dipendenti.
  • Se aggiungiamo una sovrascrittura "foo": "^2.0.0", il [email protected] verrà aggiornato a 2.0.0. Questo potrebbe interrompere il progetto poiché il [email protected] potrebbe avere alcune modifiche non retrocompatibili.

Assumendo che foo segua Semantic Versioning, possiamo aggiungere una sovrascrittura come questa:

Questo aggiornerà solo il [email protected] a 1.0.1 e manterrà il [email protected] invariato.

Conclusione

Prima che PNPM supporti l'aggiornamento diretto delle dipendenze transitive, il campo overrides è una buona soluzione per risolvere le vulnerabilità di sicurezza senza rompere nulla. Spero che questo articolo ti aiuti a gestire questi casi in modo più efficiente. In Logto, utilizziamo questo metodo per mantenere le nostre dipendenze aggiornate e sicure.