Safeey.io
Developer Tools

Scan Your Code in Seconds: A Hands-On Guide to safeey-cli

Safeey has always answered one question: what does my live site expose to an attacker? But by the time a problem shows up on your live site, it's already deployed. The mistake was in your code first.

That's why we built safeey-cli — a free, open-source command-line scanner that checks your source code for security issues before you ship. Where Safeey's web scanner looks at your site from the outside, safeey-cli looks at your code from the inside. Together they cover both halves of shipping securely.

This is a hands-on walkthrough: install it, scan a project, read the results, fix an issue, and wire it into CI. Every output below is real.

Who this is for

If you write JavaScript or TypeScript — and especially if you build fast, ship often, or lean on AI to generate code — this is for you. AI assistants optimise for code that runs, not code that's safe, and the gap is invisible when you're moving quickly. A scanner that reads your code objectively is the safety net that catches what you can't see.

And because it runs entirely on your machine, your code never leaves it. No uploads, no accounts required to scan.

Install

One command, and safeey is available anywhere in your terminal:

npm install -g safeey-cli

Verify it:

safeey --version

Your first scan

Point it at any project — a folder or a single file:

safeey scan ./

Here's what a scan of a small, insecure project looks like:

  Safeey CLI  ·  scanned 34 file(s) in ./

  src/db.js
    HIGH      Possible SQL injection            :14:10   js/sql-injection
      A SQL query is assembled by string interpolation. Injected
      input can change the query's meaning.
      fix  Use parameterised queries (placeholders + a values array).

  src/routes/user.js
    CRITICAL  Possible command injection        :22:3    js/command-injection
      A shell command is built from dynamic input and passed to exec().
      fix  Use execFile()/spawn() with an argument array (no shell).

  src/config.js
    CRITICAL  Stripe live secret key            :5:18    secret/stripe-live
      A stripe live secret key appears to be hardcoded (sk_l…f2).
      fix  Move it to an environment variable, remove it from git, and rotate it.

  ────────────────────────────────────────────────
  Risk grade F (0/100)   2 critical · 1 high

In seconds, you get a prioritised list of real problems, each with the file, the exact line, a plain-English explanation, and the fix — plus a single risk grade for the whole codebase.

Reading the results

A few things make the output easy to act on:

  • Severity first. Findings are sorted worst-first — CRITICAL, then HIGH, MEDIUM, LOW — so you fix what matters most, first.
  • Exact location. Every finding points at file:line:column. No hunting.
  • The rule ID (like js/sql-injection) tells you the category, so similar issues are easy to recognise across your codebase.
  • The fix line isn't generic advice — it tells you specifically what to change.
  • The grade (A–F) gives you a single number to track. Watch it climb as you fix things.

What it catches

safeey-cli looks for the issues that actually get applications breached. A sample:

Dangerous code executioneval() or the Function constructor called on dynamic input, and string arguments to setTimeout that behave like eval.

Command injection — shell commands built from user input via child_process.

SQL injection — queries assembled by string concatenation or template literals instead of parameters.

Cross-site scriptinginnerHTML and React's dangerouslySetInnerHTML fed dynamic content.

Hardcoded secrets — AWS, Stripe, Google, GitHub, Slack and OpenAI keys, JWTs, private keys, and generic credential assignments — all masked in the output so the scan itself doesn't leak them.

Weak or disabled crypto — MD5/SHA-1 hashing, and rejectUnauthorized: false disabling TLS checks.

Open redirects, permissive CORS, and hardcoded secret fallbacks — the small misconfigurations that quietly widen your attack surface.

Fix, then re-scan

Take that SQL injection. The flagged code looked like this:

db.query(`SELECT * FROM users WHERE email = '${email}'`);

The fix is a parameterised query — the values travel separately from the SQL, so input can never change the query's meaning:

db.query("SELECT * FROM users WHERE email = ?", [email]);

Fix the issues and run the scan again. The reward is immediate:

  Safeey CLI  ·  scanned 34 file(s) in ./

  ✔ No issues found.  (Grade A)

Watching that grade go from F to A is a genuinely satisfying loop — and a concrete signal that your codebase got safer.

Catch secrets before they're committed

Hardcoded credentials are one of the most common and damaging leaks, because anything in your code is effectively public the moment it's pushed. safeey-cli scans every file for them:

  .env.backup
    CRITICAL  Private key                :1:1    secret/private-key
      A private key appears to be hardcoded in source.
      fix  Move it to a secret manager, remove it from git history, and rotate it.

Note the value is always masked — the scanner never prints your full secret back to the screen.

Check your dependencies

A lot of real risk lives not in your code but in the packages you pull in. safeey-cli reads your package.json and flags known-vulnerable and unpinned dependencies:

  package.json
    HIGH  Known-vulnerable dependency: lodash
      lodash@4.17.11 — prototype-pollution vulnerabilities in older versions.
      fix  Update lodash to a patched version.
    LOW   Unpinned dependency version: left-pad
      left-pad is pinned to "*", which can pull in unexpected versions.

Put it in your CI pipeline

safeey-cli is built to run in automation. It returns a non-zero exit code when it finds something at or above a threshold, so it can fail a build:

safeey scan . --fail-on critical

That makes it a one-line gate in any pipeline. In GitHub Actions, for example:

- name: Security scan
  run: npx safeey-cli scan . --fail-on high

Now every push and pull request is scanned automatically, and code with high-severity issues can't merge. You catch problems at review time, not in production.

Machine-readable output

Need the results in another tool? Ask for JSON:

safeey scan . --json > report.json

You get the full findings list — rule IDs, severities, files, lines, and the grade — ready to feed into a dashboard, a bot, or your own reporting.

Sync to your Safeey dashboard

If you have a Safeey account, you can see your code scans next to your site scans in one place. Generate an API key from your dashboard, then:

safeey login <your-api-key>
safeey scan . --sync

Only the results are sent — never your source code. Your scan history builds up in the dashboard so you can track your grade over time and across projects.

The bigger picture

Security tools succeed or fail on one thing: whether you can trust them. safeey-cli is built to be precise and explainable — it points at an exact line, tells you why it's a problem, and tells you how to fix it. Clean, parameterised code scores an A; genuinely risky code gets flagged. That's the whole point.

It won't catch every possible vulnerability — no tool does — but it reliably catches the high-impact classes that account for the majority of real breaches, and it does it in seconds, for free, without your code ever leaving your machine.

Install it, scan your current project, and see what your grade is:

npm install -g safeey-cli && safeey scan ./

Then pair it with a Safeey site scan to cover both sides — your code and your live site. That's what shipping securely actually looks like.

Found this useful? Share it.

See what your site exposes

Safeey runs 1,700+ checks and shows you exactly what an attacker would find — with the fixes.

Scan your site