Static Application Security Testing (SAST) and Nodejs (with Gitlab CI)

SAST. Its a thing. Take the test to see if you need it 🙂 OK, not that SAST, the one that relates to security silly.

So I’ve been using clair from coreos. Its pretty awesome, but, to my chagrin, it does not cover python / node / go / ruby / …, the majority of the upstream culprits. (It focuses on apk/rpm/deb). So you can get a false sense of security by running it. It shocked me when I did my wiki, but then I fixed those issues and moved on and forgot. So when it came time to do my first node.js ‘express’ app, I ran it, got no hits, and was pleased with myself.

Not so fast. Turns out you need to look a bit harder, tools like snyk, retire, audit. So I picked two (retire, audit) and added them to my CI pipeline, as below:

scan:
  stage: scan
  artifacts:
    name: "$CI_PROJECT_PATH-$CI_COMMIT_REF_NAME"
    paths:
      - reports/
  script: |
    echo Analyse container $CI_REGISTRY/$CI_PROJECT_PATH:$CI_COMMIT_SHA for vulnerability
    docker tag $CI_REGISTRY/$CI_PROJECT_PATH:$CI_COMMIT_SHA $CI_PROJECT_PATH:$CI_COMMIT_SHA
    clairctl analyze -l -n --log-level debug $CI_PROJECT_PATH:$CI_COMMIT_SHA
    echo Generate JSON report
    clairctl report -l -f json $CI_PROJECT_PATH:$CI_COMMIT_SHA
    echo Generate HTML report
    clairctl report -l -f html $CI_PROJECT_PATH:$CI_COMMIT_SHA
    docker tag $CI_PROJECT_PATH:$CI_COMMIT_SHA scannee
    docker build -t scanner -f Dockerfile.scan .
    docker run --rm scanner retire --path /usr/src/app > reports/retire.js.txt 2>&1 || true
    docker run --rm scanner retire --path /usr/local/lib/node_modules/npm >> reports/retire.js.txt 2>&1 || true
    docker run -w /usr/src/app --rm scanner auditjs -r >> reports/audit.js.txt || true

Now, unlike clair, these actually need to run in the image, or maybe with it mounted somehow. So I created this very simple Dockerfile. It inherits from ‘scannee’, which I tagged the main image as above.

Now, something else I found ‘exciting’. You see that ‘USER root’? Well the origin image (scannee) has a ‘USER nonprivileged’. So here I am increasing my privilege, I did not think you could do that. Hmm.

FROM scannee
ENV NODE_ENV "production"

WORKDIR /usr/src/app

USER root

# See https://github.com/npm/uid-number/issues/3 for why the 'set unsafe-perm'
RUN npm config set unsafe-perm true  \
 && npm install -g retire \
 && npm install -g auditjs

Now my CI stage above scans (with clair), then builds a child container augmenting with retire and audit, then runs them. The original layer is unchanged, untouched.

I thought this was neat, you probably thought it was old hat.

But, it found me another hundred or so issues to dig into. And this is from node:9.11.0-alpine, its not like that is old!


Posted

in

by

Comments

One response to “Static Application Security Testing (SAST) and Nodejs (with Gitlab CI)”

  1. Node.Js Development

    Nice post! Thanks for sharing this.

Leave a Reply

Your email address will not be published. Required fields are marked *