rstudio / shiny-server

Host Shiny applications over the web.
https://rstudio.com/shiny/server
Other
712 stars 290 forks source link

Vulnerabilities from node.js? / Release of new version? #519

Closed eduardszoecs closed 2 years ago

eduardszoecs commented 2 years ago

Dear @rstudio team,

we observe using trivy some vulnerabilities by shiny-server (see summary below of a container with shiny-server and a shinydashboard application).

These could potentially be fixed by updating the node version, which was already done. đź‘Ť

Is there a plan to release this new shiny-server version with updated node any time soon? Alternatively we could build from the sources, but that's more involved....

Node.js (node-pkg)
==================
Total: 12 (MEDIUM: 10, HIGH: 1, CRITICAL: 1)
+------------------+------------------+----------+-------------------+---------------+---------------------------------------+
|     LIBRARY      | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION |                 TITLE                 |
+------------------+------------------+----------+-------------------+---------------+---------------------------------------+
| ansi-regex       | CVE-2021-3807    | MEDIUM   | 3.0.0             | 5.0.1, 6.0.1  | nodejs-ansi-regex: Regular            |
|                  |                  |          |                   |               | expression denial of service          |
|                  |                  |          |                   |               | (ReDoS) matching ANSI escape codes    |
|                  |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2021-3807  |
+                  +                  +          +-------------------+               +                                       +
|                  |                  |          | 4.1.0             |               |                                       |
|                  |                  |          |                   |               |                                       |
|                  |                  |          |                   |               |                                       |
|                  |                  |          |                   |               |                                       |
+------------------+------------------+----------+-------------------+---------------+---------------------------------------+
| follow-redirects | CVE-2022-0155    | HIGH     | 1.11.0            | 1.14.7        | follow-redirects: Exposure of         |
|                  |                  |          |                   |               | Private Personal Information          |
|                  |                  |          |                   |               | to an Unauthorized Actor              |
|                  |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2022-0155  |
+                  +------------------+----------+                   +---------------+---------------------------------------+
|                  | CVE-2022-0536    | MEDIUM   |                   | 1.14.8        | follow-redirects: Exposure            |
|                  |                  |          |                   |               | of Sensitive Information via          |
|                  |                  |          |                   |               | Authorization Header leak             |
|                  |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2022-0536  |
+------------------+------------------+          +-------------------+---------------+---------------------------------------+
| json-schema      | CVE-2021-3918    |          | 0.2.3             | 0.4.0         | nodejs-json-schema: Prototype         |
|                  |                  |          |                   |               | pollution vulnerability               |
|                  |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2021-3918  |
+------------------+------------------+          +-------------------+---------------+---------------------------------------+
| log4js           | CVE-2022-21704   |          | 6.3.0             | 6.4.0         | log4js-node is a port                 |
|                  |                  |          |                   |               | of log4js to node.js. In              |
|                  |                  |          |                   |               | affected versions defau...            |
|                  |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2022-21704 |
+------------------+------------------+          +-------------------+---------------+---------------------------------------+
| reveal.js        | CVE-2020-8127    |          | 3.3.0             | 3.9.2         | Cross-site Scripting in reveal.js     |
|                  |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2020-8127  |
+                  +------------------+          +                   +---------------+---------------------------------------+
|                  | CVE-2022-0776    |          |                   | 4.3.0         | Cross site scripting in reveal.js     |
|                  |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2022-0776  |
+------------------+------------------+----------+-------------------+---------------+---------------------------------------+
| url-parse        | CVE-2022-0686    | CRITICAL | 1.5.3             | 1.5.8         | npm-url-parse: Authorization          |
|                  |                  |          |                   |               | bypass through user-controlled key    |
|                  |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2022-0686  |
+                  +------------------+----------+                   +---------------+---------------------------------------+
|                  | CVE-2022-0512    | MEDIUM   |                   | 1.5.6         | nodejs-url-parse: authorization       |
|                  |                  |          |                   |               | bypass through user-controlled key    |
|                  |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2022-0512  |
+                  +------------------+          +                   +---------------+---------------------------------------+
|                  | CVE-2022-0639    |          |                   | 1.5.7         | npm-url-parse: Authorization          |
|                  |                  |          |                   |               | Bypass Through User-Controlled Key    |
|                  |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2022-0639  |
+                  +------------------+          +                   +---------------+---------------------------------------+
|                  | CVE-2022-0691    |          |                   | 1.5.9         | npm-url-parse: authorization          |
|                  |                  |          |                   |               | bypass through user-controlled key    |
|                  |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2022-0691  |
+------------------+------------------+----------+-------------------+---------------+---------------------------------------+
jcheng5 commented 2 years ago

Sorry for the delay, the release process was extremely protracted this time for various reasons. Shiny Server 1.5.18.987 is now available from the download page.

nreith commented 2 years ago

@jcheng5 Hi Joe,

I have been struggling with npm vulnerability whack-a-mole in the most recent shiny server version. I am using the rocker/shiny:4 docker image but confirm they're the same if I install it myself in vanilla ubuntu.

I was intrigued by your response to this previous issue from a couple of years ago. Can you clarify further which folders in /opt/shiny-server are unnecessary for the operation of the server software and could be deleted without adverse effects? If I understand correctly you're basically talking about build dependencies and it's best practice to remove those for prod images anyway.

https://github.com/rstudio/shiny-server/issues/463

jcheng5 commented 2 years ago

Hi @nreith, we already don’t install our own dependencies (the ones in node_modules) that are devDependencies in our installer based builds. In #463 what I’m referring to are basically packages that come from within Node.js’s stdlib (albeit the copy of Node.js that is private to Shiny Server). It’s definitely not best practice to mess with those.

That being said, I’m tired of playing security vulnerability whack-a-mole too. In 2023 I sure would like to get some time to strip away unneeded dependencies. Some of them are way more trouble than they have been worth.

nreith commented 1 year ago

I spent a lot of time deep diving on how to fix npm vulnerabilities and wanted to share what I came up with that worked. This is the section of my Dockerfile that got me to 0 high and 0 critical, with shiny-server still working.

A couple small notes.

  1. You may not want to remove the npm cli yourselves as a base image, but that really depends on if you expect yourselves or users to ever install things with npm and they can get it back easily enough. I think what node packages shiny-server comes with is what you get, and probably users will only ever be installing apt or R packages.

  2. I wrote a shell script initially to find and dive into every folder with a package.json and do some of the same steps like... remove unused/dev/duplicates, etc. It was way too slow and time consuming, and ultimately not really necessary. Seems best to start from the top down and ignore anything not coming up as high/critical. Biggest bang for my buck was simply deleting npm.


# Security fixes
###################
ENV PATH=${PATH}:/opt/shiny-server/bin:/opt/shiny-server/ext/node/bin
WORKDIR /opt/shiny-server
RUN \
  # remove security keys
  rm -f /etc/ssh/ssh_*_key && \
  # NOTE: The use of npx in the following commands allows you to run a command directly without first installing the package.
  #   It will install it, and execute, but in a global cache, where it can easily be removed after with cache clean
  #
  # List unused dependencies and dev dependencies
  npx depcheck -y --oneline --skip-missing=true | grep -v "^No depcheck issue\|^Unused" | tr ' ' '\n' | sort | uniq >| unused && \
  echo "### The following are reporting as unused:" && cat unused && \
  cat package.json | grep -A1000 devDependencies | sed 's/^  *//g' | grep -v "devDependencies\|^}" | cut -d'"' -f2 | sort | uniq >| dev && \
  echo "### The following are reporting as dev dependencies only:" && cat dev && \
  # Remove unused or dev dependencies
  #   We won't automate removal though because some are false positives as "unused" or "dev"
  #   The only way is to remove all unused/dev, then progressively try again and again by not removing the ones that cause errors
  toremove="graceful-fs mocha nan sockjs-client rewire should sinon" && \
  for dep in ${toremove}; do echo "Uninstalling ${line}"; npm uninstall $dep; done && \
  rm -f unused dev && \
  # Deduplicate npm packages, removing duplicates if one exists higer up the tree
  npx -c 'npm dedupe' && \
  # Fix vulnerabilities if high or critical. We don't use the --force argument to avoid known breaking changes.
  npm audit fix --audit-level=high && \
  # Uninstall installed dependencies
  npm uninstall -g depcheck npm-dedupe && \
  #
  # Clear cache
  # NOTE: We do this with --force, but consider it safe because the cache is not needed except to build packages 
  #   or avoid installing ones already built. This makes the image smaller and more secure.
  #   And we won't install additional shiny-server or node/npm packages after docker build. Only R packages.
  npm cache clean --force && \
  #
  # After a lot of investigation of the twistlock reports, after.json was full of vulnerabilities from this older version of npm
  # Decided to simply remove the npm package instead of updating
  rm -rf /opt/shiny-server/ext/node/lib/node_modules/npm  /opt/shiny-server/bin/npm
  # However, if you prefer to upgrade, note: you can go from 6.14.15, to 6.14.17 but it is still full of vulnerabilities
  # If you want to go any higher, it is v7.x.x, and is a breaking change. Even though shiny-server specifies >=2.8.0 for npm, 
  #   it's risky and may still have vulnerabililities. The src code for shiny-server makes no mention of npm.
  # We should be able to treat npm like a build dependency since it isn't needed after image build for installing npm packages.
  # npm install --prefix /opt/shiny-server/ext/node/lib npm@"~6.14.17"
eduardszoecs commented 1 year ago

Thanks @nreith for sharing,

here's what I ended up with

RUN \
  # fetch shrinkwrap.json from github
  wget https://raw.githubusercontent.com/rstudio/shiny-server/master/npm-shrinkwrap.json && \
  # Fix vulnerabilities. Exit with 0 if all high are resolved
  npm audit fix --audit-level=critical && \
  # update missed fix https://github.com/npm/cli/issues/3472
  npm update minimatch && \
  # remove the npm package as it's only a build dep
  # https://github.com/rstudio/shiny-server/issues/519#issuecomment-1242488576
  rm -rf /opt/shiny-server/ext/node/lib/node_modules/npm  /opt/shiny-server/bin/npm && \
  # Alibaba access key in npm cache (false positive?)
  rm -rf /root/.npm/_cacache/content-v2/sha512