Upgrade transitive dependencies met PNPM: Los de beveiligingsproblemen op zonder dingen te breken
Het oplossen van beveiligingsproblemen kan een frustrerende taak zijn, vooral wanneer het om transitieve afhankelijkheden gaat. Leer hoe je ze kunt upgraden zonder je directe afhankelijkheden te beïnvloeden.
Tegenwoordig zijn beveiligingsproblemen een veelvoorkomend probleem in softwareontwikkeling. Gelukkig hebben we tools zoals GitHub Dependabot om ons te helpen onze afhankelijkheden up-to-date te houden met geautomatiseerde detectie en pull requests.
Echter, het werkt niet altijd zoals verwacht. Aangezien sommige afhankelijkheden transitief zijn, kan het upgraden van hen een moeilijke taak zijn voor deze tools omdat ze de impact van de veranderingen niet kennen en niet weten welke beslissing ze moeten nemen wanneer er conflicten zijn. We moeten deze gevallen handmatig afhandelen.
Methodes die niet werken
- Officiële commando's zoals
pnpm up
zullen jepnpm-lock.yaml
bestand in de war sturen. Er is een probleem hierover dat nog steeds openstaat op het moment van schrijven. - Het installeren van de laatste versie van de directe afhankelijkheid die de doel-transitieve afhankelijkheid heeft, werkt mogelijk niet. Als de directe afhankelijkheid de versie-definities niet heeft geüpgraded, zal de transitieve afhankelijkheid niet worden geüpgraded aangezien deze is opgelost en vergrendeld in het
pnpm-lock.yaml
bestand.
De oplossing
Het overrides
veld is een krachtige functie in PNPM die je toestaat om sommige versie-resoluties te overschrijven. We zullen deze functie gebruiken om transitieve afhankelijkheden te upgraden en de verandering zo minimaal mogelijk te houden.
Laten we de bovenstaande Dependabot-melding als voorbeeld nemen. Het vertelt ons dat het follow-redirects
pakket een beveiligingsprobleem heeft en de gepatchte versie is 1.15.6
. Echter, de directe afhankelijkheid gatsby
gebruikt axios
die afhankelijk is van [email protected]
.
Stap 1: Vind de transitieve afhankelijkheid
Er zijn veel manieren om de transitieve afhankelijkheid te lokaliseren, maar ik zou de meest directe manier aanbevelen: zoek in het pnpm-lock.yaml
bestand.
Hoe zit het met "pnpm why"?
Het pnpm why <package>
commando is inderdaad nuttig. Echter, het kan je verwarren in dit geval. Bijvoorbeeld, wanneer ik pnpm why follow-redirects
uitvoer, hier is een deel van de uitvoer:
Er is eigenlijk maar één resolutie voor follow-redirects
in het pnpm-lock.yaml
bestand. Het pnpm why
commando kan je meerdere paden tonen die afhankelijk zijn van dezelfde versie van het pakket.
Stap 2: Voeg de overrides toe
Het makkelijkste geval is dat er slechts één resolutie bestaat in het pnpm-lock.yaml
bestand. Je kunt de override direct toevoegen aan het package.json
bestand:
Als je in een werkruimte bent, moet je de override toevoegen aan het hoofd package.json
bestand van de werkruimte.
Stap 3: Pas de veranderingen toe
Voer pnpm install
uit om de veranderingen toe te passen. We kunnen zien dat het follow-redirects
pakket is geüpgraded naar 1.15.6
in het pnpm-lock.yaml
bestand met minimale veranderingen.
Nu kan je het overrides
veld uit het package.json
bestand verwijderen om het schoon te houden. Voer dan pnpm install
opnieuw uit om te valideren dat de veranderingen kunnen worden toegepast zonder het overrides
veld.
Problemen oplossen
De bovenstaande stappen zijn het ideale geval. Dingen gaan misschien niet altijd zoals verwacht. Hier zijn enkele tips voor het oplossen van problemen:
De versie wordt teruggezet na het verwijderen van het "overrides" veld
Dit kan gebeuren wanneer het afhankelijke pakket een vaste versie heeft of een bereik dat de doelversie niet omvat. Controleer het package.json
bestand van het afhankelijke pakket, in dit geval axios
, om te zien of dit van toepassing is.
Indien zo, moet je het overrides
veld in het package.json
bestand houden totdat het afhankelijke pakket de versie-definities upgraden.
Er zijn meerdere resoluties voor de transitieve afhankelijkheid
Naarmate het project groeit, kan het pnpm-lock.yaml
bestand vervullen van meerdere resoluties voor hetzelfde pakket. Bijvoorbeeld, er kunnen twee belangrijke versies zijn van hetzelfde pakket foo
:
Het kwetsbaarheidsrapport toont dat [email protected]
een beveiligingsprobleem heeft dat is opgelost in 1.0.1
, en [email protected]
is niet beïnvloed. We konden niet zomaar een override toevoegen aan foo
:
- Als we een override toevoegen
"foo": "^1.0.1"
, zal de[email protected]
worden gedowngraded naar1.0.1
. Dit kan het project breken aangezien de[email protected]
mogelijk enkele nieuwe functies heeft die worden gebruikt in de afhankelijke pakketten. - Als we een override toevoegen
"foo": "^2.0.0"
, zal de[email protected]
worden geüpgraded naar2.0.0
. Dit kan het project breken aangezien de[email protected]
mogelijk enkele breekbare veranderingen heeft.
Aangezien foo
Semantische Versiecontrole volgt, kunnen we een override toevoegen zoals deze:
Dit zal alleen de [email protected]
upgraden naar 1.0.1
en de [email protected]
ongewijzigd laten.
Conclusie
Voordat PNPM het direct upgraden van transitieve afhankelijkheden ondersteunt, is het overrides
veld een goede oplossing om beveiligingsproblemen op te lossen zonder dingen te breken. Ik hoop dat dit artikel je helpt om deze gevallen efficiënter aan te pakken. Bij Logto gebruiken we deze methode om onze afhankelijkheden up-to-date en veilig te houden.