nodesec_cli
v1.0.0
Published
Node.js backend security checklist: automated scanners (npm audit, JWT/session config, dangerous sinks, secrets, dependency risk) plus a guided manual checklist covering OWASP API Security Top 10 style risks (BOLA, BFLA, mass assignment, SSRF, CORS). Ship
Maintainers
Readme
nodesec_cli
Node.js backend security checklist tool — automated static scanners plus a guided manual checklist, covering the risk areas from OWASP's API Security Top 10 and common Node.js backend failure modes: Broken Object Level Authorization (BOLA/IDOR), Broken Function Level Authorization (BFLA), mass assignment, authentication and JWT config, session/cookie hardening, request limits, npm dependency/supply-chain risk, secrets management, SSRF, and CORS.
Ships as both a CLI (nodesec_cli) and a local web dashboard
(nodesec_cli web), backed by a shared SQLite database so scan results and
checklist answers persist across runs and across CLI/web usage.
This tool runs static, best-effort checks against your own source code and
npm auditoutput. It does not send your code anywhere, does not make network calls to your target application, and does not attempt exploitation. Findings are leads for manual review, not proof of exploitability — and absence of findings is not proof of security.
Contents
- Install
- Quick start
- CLI reference
- Web dashboard
- What gets checked automatically
- The manual checklist
- Scoring
- Data storage
- Architecture
- Development
- Limitations
- License
Install
npm install -g nodesec_cliOr run it without installing globally:
npx nodesec_cli scan .Requires Node.js 18+.
Quick start
# 1. Run automated scanners against a target Node.js project
nodesec_cli scan /path/to/your-backend
# 2. Walk through the manual checklist for anything scanners can't detect
nodesec_cli checklist /path/to/your-backend
# 3. View the combined report
nodesec_cli report /path/to/your-backend
# Or do the same thing in a browser:
nodesec_cli web
# → open http://localhost:4300, enter the project path, and goCLI reference
nodesec_cli scan <path>
Runs all automated scanners against the target directory, stores the results, and prints a category score table plus a findings table (severity, category, message, file:line).
nodesec_cli scan ./my-apinodesec_cli checklist <path> [--category <category>]
Interactively walks through the manual checklist items (one prompt per item: Pass / Fail / Not applicable, plus optional notes). Re-running it shows your previous answers as defaults, so you can update a checklist incrementally instead of redoing it from scratch.
nodesec_cli checklist ./my-api
nodesec_cli checklist ./my-api --category "Object Authorization"nodesec_cli report <path> [--format md|json] [--out <file>]
Prints (or writes to a file) the combined report: overall score, category scores, automated findings, and manual checklist answers.
nodesec_cli report ./my-api
nodesec_cli report ./my-api --format json --out report.jsonnodesec_cli list
Lists every project that has been scanned, with its path and latest overall score.
nodesec_cli listnodesec_cli web [--port <port>]
Starts the local web dashboard (default port 4300), backed by the same
SQLite database as the CLI.
nodesec_cli web
nodesec_cli web --port 8080Web dashboard
nodesec_cli web starts an Express server with a small static dashboard:
- Enter a project path and click Run Scan to trigger the same automated scanners as the CLI.
- Browse category scores and the automated findings table.
- Fill in the manual checklist inline — each item has a status dropdown (Pass / Fail / Not applicable) and a notes field, saved on change/blur.
- Click a previously-scanned project card to reopen its latest report.
The dashboard is local-only: no authentication, no multi-user support, no external services. It's meant to be run on your own machine or a trusted internal network — do not expose it directly to the internet.
What gets checked automatically
Each scanner is a best-effort static/regex check over your source tree (or
npm audit output) — not full semantic analysis. Expect some false
positives and false negatives; treat findings as things to go verify, not
ground truth.
| Scanner | Checks |
|---|---|
| node-version | package.json engines.node targets a supported (non-EOL) Node.js major version |
| npm-audit | Runs npm audit --omit=dev --json in the target repo and surfaces high/critical/moderate advisories |
| lockfile | package-lock.json exists and isn't gitignored |
| helmet-headers | Express app uses Helmet, disables X-Powered-By, and doesn't combine cors({ origin: '*' }) with credentials: true |
| body-limits | express.json() / bodyParser.json() calls set an explicit limit |
| secrets-scan | Source files for hardcoded-looking secrets (AWS keys, generic API key assignments, private key blocks, Slack tokens) |
| dangerous-sinks | Use of eval(), new Function(), child_process.exec(), vm.runInNewContext() |
| jwt-config | jwt.verify() calls pin an algorithms allowlist and validate issuer/audience |
| session-cookie | Session/cookie config sets httpOnly, secure, and an explicit sameSite |
| env-files | .env is not tracked by git (checked via git ls-files) |
The manual checklist
37 items grouped into 13 categories that automated static analysis can't reliably answer on its own — each item is written to be testable against actual application behavior, not just "use authorization" style advice:
API Inventory · Object Authorization (BOLA/IDOR) · Function Authorization (BFLA) · Property Authorization (mass assignment) · Authentication · JWT · Sessions & Cookies · Request Limits · Dependencies · Runtime · Logging · SSRF · Secrets · CORS · Dangerous Code Execution.
Each item includes a plain-language question and a testableDescription
explaining exactly what to verify (e.g. "User A requesting User B's object
(same role, same/different tenant) returns 403/404, not 200 with data.").
Scoring
- Each category score is
passed / total * 100, wheretotalcounts both answered checklist items (excluding "not applicable") and automated findings in that category (each finding counts as one failed check). - The overall score is a weighted average across categories, with an
additional penalty subtracted for
criticalandhighseverity findings — so a handful of critical issues drags the score down faster than the category average alone would suggest.
Data storage
All scan results and checklist answers are stored in a local SQLite
database at ~/.sec-check/sec-check.db (both the CLI and the web dashboard
read/write the same file). Override the location with:
SEC_CHECK_HOME=/custom/path nodesec_cli scan .Nothing is sent anywhere — this is a fully local, offline tool.
Architecture
This repo is an npm-workspaces monorepo with three packages; only
packages/cli is published to npm (as nodesec_cli), with the other two
bundled into it at publish time.
packages/
core/ @sec-check/core — SQLite layer, checklist seed data, scanners, scoring, report generation
web/ @sec-check/web — Express API + static dashboard (imported by cli's `web` command)
cli/ nodesec_cli — the published package: commander CLI + bundles core/web into its own node_modulespackages/cli/scripts/bundle-workspaces.mjs copies the built core and
web packages into packages/cli/node_modules/@sec-check/* before publish,
and bundledDependencies in packages/cli/package.json tells npm to
include them in the published tarball — so an end user installing
nodesec_cli gets a fully self-contained package with no dependency on this
monorepo's workspace setup.
Development
npm install
npm run build # builds core -> web -> cli in dependency order
npm test # vitest, currently in packages/core
npm run lint # eslint across all packages
npm run cli -- scan . # run the CLI from source
npm run web # run the web dashboard from sourcePublishing
npm run prepare-publish # build all packages + bundle core/web into cli's node_modules
cd packages/cli
npm pack --dry-run # sanity-check the tarball contents first
npm publishLimitations
- Scanners are regex/heuristic-based static analysis, not an AST-level or data-flow analysis — they can miss issues hidden behind indirection and can flag safe code that happens to match a pattern.
npm-auditshells out to thenpmbinary in the environment running the scan; ifnpmisn't onPATHor the target has nopackage.json, that scanner reports nothing instead of failing the whole scan.- The manual checklist requires a human to actually test the behavior it describes (e.g. cross-tenant object access) — this tool doesn't send traffic to your application or attempt any exploitation.
- The web dashboard has no authentication and is intended for local/trusted use only.
License
MIT
