Skip to content

Instantly share code, notes, and snippets.

@fhemberger
Last active February 10, 2021 21:37
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fhemberger/850938506d2e2e1f963423d59a9092c6 to your computer and use it in GitHub Desktop.
Save fhemberger/850938506d2e2e1f963423d59a9092c6 to your computer and use it in GitHub Desktop.
Node.js: Create checksums for npm's 'postinstall' actions

Node.js: Create checksums for npm's 'postinstall' actions

After watching Patrick Debois' talk from DeliveryConf »How Secure Is Your Build / Server?«, I tried to get at least a rough idea if postinstall steps where running at all and if they do the same things after a package update.

So I wrote a little proof of concept that will:

  • Create a Dockerfile, using package.json and package-lock.json from a Node.js project in the current directory
  • Install all its dependencies inside the Docker container first, without running any postinstall steps, then do the same with running the scripts.
  • Reading the diff of those steps using Docker's image layers
  • And calculate a checksum of those changes.

So when you update any dependencies and run the script again, you should be able to tell if something inside the postinstall step changed and dig deeper into the issue.

Requirements

  • Node.js
  • Docker on Linux (Docker for Mac/Windows doesn't expose /var/lib/docker/overlay2)
#!/usr/bin/env bash
set -uo pipefail
if [ ! -d "/var/lib/docker/overlay2" ]; then
>&2 echo "Could not find '/var/lib/docker/overlay2' directory. Do you have Docker installed?"
exit 1
fi
readonly IMAGE="$(node -e "const pkg=require('./package.json');console.log(pkg.name+'@'+pkg.version);" 2> /dev/null)"
if [ -z "$IMAGE" ]; then
>&2 echo "Could not determine Node.js package information in current directory."
exit 1
fi
set -e
>Dockerfile echo "FROM node:${NODE_VERSION:-latest}
COPY package* /
RUN npm ci --ignore-scripts
# basically the same as above, this time exectuting post-install scripts
RUN npm install"
docker build -t "verify/$IMAGE" .
readonly LAYER="$(docker history "verify/$IMAGE" --format '{{ .ID }}\t{{ .CreatedBy }}' | grep '/bin/sh -c npm install' | awk '{ print $1 }')"
if [ -z "$LAYER" ] || [ "$LAYER" == '<missing>' ]; then
>&2 echo "No post-install layer found."
exit
fi
find "/var/lib/docker/overlay2/$LAYER/diff" -type f -print0 | LC_ALL=POSIX sort -z | xargs -0 sha256sum | sha256sum > "${IMAGE}-postinstall.sha256"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment