Exercise - Manage dependency updates in your Node.js project

Completed

Tailwind Traders has asked you to work on an app that has some outdated dependencies. The app is small and has only a few dependencies. Updating the code should be straightforward. See if you can update the app to take advantage of the latest features. While you're at it, if you find any vulnerabilities, fix them.

Get started

  1. In a new terminal window (Ctrl + Shift + `), change to the folder that has the files for this exercise:

    cd ../7-exercise-dependency-management
    
  2. Install the dependencies by running this command:

    npm install
    

    You should see output about the packages installed and any vulnerabilities.

  3. Open the package.json file and look at the dependencies section:

    "lodash": "^1.1.0",
    "node-fetch": "^1.0.2"
    

    Notice the patterns specify the insert (^) character, which indicates updates to the minor version to support dependencies: 1.x.

  4. Open the index.js file to understand how the package dependencies are used in the app:

    const fetch = require('node-fetch')
    const _ = require('lodash');
    const path = require('path');
    const fs = require('fs');
    
    async function run() {
      const response = await fetch("https://dev.to/api/articles?state=rising");
      const json = await response.json();
      const sorted = _.sortBy(json, ["public_reactions_count"], ['desc']);
      const top3 = _.take(sorted, 3);
    
      const filePrefix = new Date().toISOString().split('T')[0];
      fs.writeFileSync(path.join(__dirname, `${filePrefix}-feed.json`), JSON.stringify(top3, null, 2));
    }
    
    run();
    

    This code pulls data from a REST API by using the node-fetch package. It processes the response by sorting it and takes the top three results by using the lodash package. The result is stored in a file.

npm audit

To understand if there are any vulnerabilities, run this command:

npm audit

You should see output similar to this example:

# npm audit report

lodash  <=4.17.20
Severity: critical
Regular Expression Denial of Service (ReDoS) in lodash - https://github.com/advisories/GHSA-x5rq-j2xg-h7qm
Prototype Pollution in lodash - https://github.com/advisories/GHSA-fvqr-27wr-82fm
Prototype Pollution in lodash - https://github.com/advisories/GHSA-jf85-cpcp-j695
Command Injection in lodash - https://github.com/advisories/GHSA-35jh-r3h4-6jhm
Prototype Pollution in lodash - https://github.com/advisories/GHSA-4xc9-xhrj-v574
Regular Expression Denial of Service (ReDoS) in lodash - https://github.com/advisories/GHSA-29mw-wpgm-hmr9
fix available via `npm audit fix --force`
Will install lodash@4.17.21, which is a breaking change
node_modules/lodash

node-fetch  <=2.6.6
Severity: high
The `size` option isn't honored after following a redirect in node-fetch - https://github.com/advisories/GHSA-w7rc-rwvf-8q5r
node-fetch forwards secure headers to untrusted sites - https://github.com/advisories/GHSA-r683-j2x4-v87g
fix available via `npm audit fix --force`
Will install node-fetch@3.3.2, which is a breaking change
node_modules/node-fetch

2 vulnerabilities (1 high, 1 critical)

To address all issues (including breaking changes), run:
npm audit fix --force

The output states the vulnerabilities and the version of the package that fixes the issue.

Will install lodash@4.17.21, which is a breaking change
Will install node-fetch@3.3.2, which is a breaking change

npm outdated

In the terminal, run this command to check for outdated dependencies:

npm outdated

You should see output similar to this example:

Package     Current  Wanted   Latest  Location                 Depended by
lodash        1.3.1   1.3.1  4.17.21  node_modules/lodash      7-exercise-dependency-management
node-fetch    1.7.3   1.7.3    3.3.2  node_modules/node-fetch  7-exercise-dependency-management

The current and wanted versions are the same, but the latest version is different. The semantic update strategy specified in the package.json has been met but the vulnerabilities still exist.

npm update

  1. Edit the package.json file to explicitly allows for major changes to fix the vulnerabilities starting with the more significant package:

    "node-fetch": "^2.6.6"
    
  2. Run this command to see what update would do:

    npm update --dry-run
    
    added 3 packages, removed 4 packages, and changed 1 package in 508ms
    
  3. Run this command to update the project based on the package.json:

    npm update
    
  4. Run this command to see the vulnerability for node-fetch has been fixed:

    npm audit
    
    # npm audit report
    
    lodash  <=4.17.20
    Severity: critical
    Regular Expression Denial of Service (ReDoS) in lodash - https://github.com/advisories/GHSA-x5rq-j2xg-h7qm
    Prototype Pollution in lodash - https://github.com/advisories/GHSA-fvqr-27wr-82fm
    Prototype Pollution in lodash - https://github.com/advisories/GHSA-jf85-cpcp-j695
    Command Injection in lodash - https://github.com/advisories/GHSA-35jh-r3h4-6jhm
    Prototype Pollution in lodash - https://github.com/advisories/GHSA-4xc9-xhrj-v574
    Regular Expression Denial of Service (ReDoS) in lodash - https://github.com/advisories/GHSA-29mw-wpgm-hmr9
    fix available via `npm audit fix --force`
    Will install lodash@4.17.21, which is a breaking change
    node_modules/lodash
    
    1 critical severity vulnerability
    
    To address all issues (including breaking changes), run:
      npm audit fix --force
    
  5. If your project has any tests, run them to verify the update didn't break anything.

  6. Use these same steps to update lo-dash to the 4.17.20 version without vulnerabilities.

    The vulnerabilities are fixed but the node-fetch version is still a major version behind. If all your tests pass, correct the version specified in the package.json file to the latest version:

    "node-fetch": "^3.3.2"
    
  7. Then run the following command to update the project:

    npm update
    

    Your project should now have no npm vulnerabilities and be on the current major version.

  8. Check in your package.json and package-lock.json files.

    Congratulations! You've updated the dependencies and fixed the vulnerabilities in the project.

Cleanup development container

After completing the project, you may wish to clean up your development environment or return it to its typical state.

Deleting the GitHub Codespaces environment ensures that you can maximize the amount of free per-core hours entitlement you get for your account.

Important

For more information about your GitHub account's entitlements, see GitHub Codespaces monthly included storage and core hours.

  1. Sign into the GitHub Codespaces dashboard (https://github.com/codespaces).

    Screenshot of all the running codespaces including their status and templates.

  2. Open the context menu for the codespace and select Delete.

    Screenshot of the context menu for a single codespace with the delete option highlighted.