Skip to content

Releases: sabahattink/codediag

v0.13.0 - Scope

Choose a tag to compare

@sabahattink sabahattink released this 02 Nov 20:09
aa400cf

The "Scope" release: Elysia analysis. In Elysia, a hook is local to the plugin that registers it unless it says { as: 'scoped' } or { as: 'global' }, and it applies only to routes registered after it. An auth plugin that forgets the scope, or a route registered one line too early, leaves a route open while the code looks protected. CodeDiag now models both.

npx @sabahattink/codediag scan .

Highlights

  • Routes followed through plugins. Routes on new Elysia() instances are traced through prefix, group(), guard(), and use() across files, functional plugins and tsconfig path aliases included, and replayed in registration order.
  • Auth where Elysia runs it. onBeforeHandle(), a derive() or resolve() that rejects with 401 or 403, guard(), auth macros such as better-auth's { auth: true }, onRequest(), or a check in the handler. A derive() that only adds user to the context does not count.
  • The hook that did not reach. When an auth hook exists but stays local to its plugin, or comes after the route, the finding names the hook and its line.
  • Body validation from TypeBox, Zod, or any Standard Schema in the route options or a guard(), only for handlers that actually read the body.
  • "Routes not analyzed." On a Koa, Hapi, Nuxt, Astro, or other server CodeDiag has no analyzer for, the report says so instead of showing no route findings.

Checked against db-studio, ConvertX, ohmyblog, and two Elysia starters. Suggested by a reader on Indie Hackers. See the changelog.

v0.12.0 - Rows

Choose a tag to compare

@sabahattink sabahattink released this 02 Nov 19:37
d965ab8

The "Rows" release. In a Supabase app the browser holds the anon key and queries the database directly, so row level security, not your API routes, decides who can read and write a table. CodeDiag now checks it in your migrations.

npx @sabahattink/codediag scan .

Highlights

  • Tables without RLS are critical. CodeDiag replays supabase/migrations in order: renames, schema moves, drops, disable row level security, and revoke all from anon and authenticated. Any table that ends up in an exposed schema without RLS is reported at its create table line. Exposed schemas are public by default, or the ones in supabase/config.toml.
  • Policies open to every row. CodeDiag flags update, delete, or all policies whose using is true, and anon insert policies whose with check is true. Public read policies are left alone.
  • SQL-aware. Comments, strings, and function bodies never count. A table that is public on purpose can be suppressed with a -- codediag-ignore-next-line comment and a reason.
  • What a clean scan does not mean is now spelled out in the README: object-level authorization, policy conditions, Server Actions, and more.

Checked against vercel/nextjs-subscription-payments, Basejump, and chatgpt-your-files. Suggested by a reader on Indie Hackers. See the changelog.

v0.11.2 - Signed webhooks

Choose a tag to compare

@sabahattink sabahattink released this 01 Nov 20:37
d59aab4

A false-positive fix from launch feedback.

  • Signed webhooks count as authenticated in Next.js, Express, Fastify, Hono, and NestJS. SvelteKit and React Router already counted them. A webhook has no session by design; it proves the sender with a signature. Those routes were reported as missing auth. CodeDiag now recognizes:
    • Stripe constructEvent();
    • Svix verify();
    • an HMAC compared with timingSafeEqual();
    • helpers or middleware such as verifyGithubSignature or verifySlackSignature, including in a named handler function.

Thanks to the Indie Hackers reader who reported it. See the changelog.

v0.11.1 - Plugin fix

Choose a tag to compare

@sabahattink sabahattink released this 01 Nov 20:14
aef7bd3

A fix for the Claude Code plugin.

  • The plugin's MCP server now starts @sabahattink/codediag@latest. With a bare package name, npx used a copy already installed in the project. Inside the CodeDiag repository that copy can't run, so the server didn't start. In a project with an older devDependency, it would run a version that has no mcp command.

If you installed the plugin on 0.11.0, update it from /plugin and the server will connect.

See the changelog.

v0.11.0 - Agents

Choose a tag to compare

@sabahattink sabahattink released this 01 Nov 19:48
ff6c511

The "Agents" release: your coding agent can now ask CodeDiag which API routes anyone can call, through an MCP server, an Agent Skill, or a Claude Code plugin.

/plugin install codediag --marketplace sabahattink/codediag

Highlights

  • MCP server — codediag mcp: three read-only tools for any MCP client.

    • find_unprotected_routes: routes, form actions, and procedures with no recognizable auth check or input validation. Always offline.
    • scan_project: the 0–100 score and findings, most severe first. The dependency audit runs only when you ask for it.
    • explain_rule: what a rule detects and how to suppress it.

    Results are structured and schema-checked. The server adds no runtime dependencies, and a test runs it against the official MCP SDK client.

  • Claude Code plugin: one install adds the server and a skill.

  • Agent Skill: npx skills add sabahattink/codediag. It tells any agent where each framework runs auth, and to check a finding before calling a route vulnerable.

  • MCP Registry: listed as io.github.sabahattink/codediag.

Setup for Claude Code, Cursor, VS Code, and Claude Desktop is in the AI agents guide. The changelog has the details.

v0.10.0 - Reach

Choose a tag to compare

@sabahattink sabahattink released this 01 Nov 18:06
3cb3fbd

The "Reach" release: SvelteKit and React Router/Remix get API Health analysis, Next.js middleware is judged for each route the way it runs, tRPC perimeters cover Hono, Fastify, and Auth.js, pnpm workspaces stop reporting each other's vulnerabilities, and password and secret checks stop flagging ordinary sign-up code.

npx @sabahattink/codediag@0.10.0 scan .

Highlights

  • SvelteKit: +server endpoints and form actions, with auth in the handle hook or the handler. CodeDiag says so when the only auth check sits in a layout load, which never runs for actions. It also flags missing body validation and disabled CSRF origin checks.
  • React Router and Remix: actions and loaders from app/routes.ts or flat-route files, with route middleware as a perimeter. A separate rule covers auth that only lives in a parent's or the route's own loader, since neither runs before an action.
  • Next.js middleware, run per route: a guard for /dashboard no longer protects /api, and clerkMiddleware() alone no longer counts as auth. Auth.js authorized callbacks and Supabase's updateSession() are understood.
  • tRPC perimeters: auth before Hono's trpcServer(), auth hooks over Fastify's tRPC plugin, and Auth.js v5 middleware.
  • One pnpm audit per workspace: each package reports only the advisories its own dependencies reach.
  • Fewer false positives: sign-up validation, error messages, test fixtures, Pwned Passwords lookups, and MOCK_ placeholders are no longer critical findings. On the Remix indie-stack, Security goes from 3 to 78; on the Epic Stack, from 0 to 72.
  • VS Code 0.8.0 runs the new engine.

This release also ships 0.9 "Perimeter", which was not published on its own:

  • tRPC auth in createContext, Express mounts, and Next.js middleware;
  • dependency audits cached for an hour and run concurrently across workspace packages;
  • Dependabot updates that rebuild the Action bundle.

See the changelog for details.

v0.8.0 - Depth

Choose a tag to compare

@sabahattink sabahattink released this 30 Oct 12:13
c1643d0

The "Depth" release: tRPC procedures, request data followed through fields, constructors, callbacks, and injected providers, fastify-cli projects as @fastify/autoload loads them, secrets that Git history still holds, gates that a good average cannot hide, and fixes you apply from the editor.

npx @sabahattink/codediag@0.8.0 scan .

Highlights

  • tRPC: procedures are followed from initTRPC through .use() chains, exported builders such as protectedProcedure, and nested or merged routers across files. New warnings: missing-trpc-auth-middleware, unvalidated-trpc-input, trpc-stack-trace-exposed. The checks run inside whichever server hosts tRPC, so T3 App Router projects get a real API Health score. Procedure input counts as request data for the security rules, even after .input(schema).
  • Deeper taint: request data is followed into fields a class stores it in, through constructors, into map/forEach/reduce/then callbacks and for...of, and to NestJS providers behind an interface or @Inject() token. Findings stay on the sink line with unchanged fingerprints.
  • Fastify autoload: fastify-cli projects get directory prefixes, autoPrefix, and autohooks the way @fastify/autoload applies them, instead of false missing-auth warnings.
  • Secrets in Git history (opt-in): --secret-history reports credentials that a commit added and a later one deleted. Secrets are compared by digest and never printed.
  • Gates: --fail-on critical fails on any active critical finding whatever the score; --package-threshold 70 gates every monorepo package on its own score. Both work in the GitHub Action (fail-on, package-threshold).
  • VS Code 0.6.0: remediation quick fixes for disabled TLS verification, ignored JWT expiration, and the JWT none algorithm.

Fixes

  • NestJS @Param()/@Query()/@Body()/@Headers() parameters now make shell command and SQL findings critical; parameters behind a parsing pipe (ParseIntPipe, ...) are not request data.
  • Action annotation messages no longer show commas and colons as %2C and %3A.
  • The JSON schema accepts combined workspace reports with Hono packages.

See the changelog for details and known limitations.

v0.7.0 — Across

Choose a tag to compare

@sabahattink sabahattink released this 30 Oct 00:44
802f00a

Across: CodeDiag follows request data through your own helper functions and services, scans whole monorepos as one report, analyzes Hono apps, tracks your score over time, and measures pull requests against the base branch.

npx @sabahattink/codediag@0.7.0 scan . --workspaces --history .codediag/history

Cross-file taint

Request data passed into project helpers and services is followed up to two calls deep:

// src/lib/convert.ts
export function convert(file: string) { exec(`convert ${file}`); }   // ← critical now
// src/routes/upload.ts
router.post("/convert", auth, (req, res) => convert(req.body.file));
  • All import styles, class methods, and NestJS this.service.method(dto.x) are followed.
  • Pass-through helpers such as getName(req) carry request data back to the caller.
  • Findings stay on the sink line with unchanged messages and fingerprints, marked confidence: "medium". The fix text names the calling line.
  • On every existing fixture the findings are the same as before, and CodeDiag's own scan got faster.

Monorepos

--workspaces scans every package of an npm, pnpm, or Yarn workspace, a Lerna repository, or an Nx workspace:

  • Each package gets its own stack detection and its own config.
  • The combined report lists every package and averages each analyzer over the packages it ran in.
  • Baselines, --compare, --changed-since, and SARIF work across the whole repository.
  • The GitHub Action (workspaces: true) and the VS Code extension support it too.

Hono

The new API Health analyzer reads Hono apps:

  • routes, basePath(), and sub-apps mounted with app.route() across files, replayed in Hono's registration order
  • jwt(), bearerAuth(), and custom auth middleware
  • zValidator body validation
  • onError and health endpoints

There are four new rules (80 → 84). Hono servers are also checked for secure headers, rate limiting, and open hono/cors.

Score history

--history <dir> records every scan. The terminal shows a sparkline. The HTML report shows a line chart with grade guides, keyboard-reachable readouts, and a table view.

Base-branch delta in pull requests

Give the Action your base branch's report with compare: codediag-main.json. The comment then reads ▼ −3 vs. the base branch (81) · 1 new · 2 fixed, and new findings are marked.

Also

  • Vulnerability findings name the affected packages and their advisories.
  • audit: production skips devDependencies.
  • --format prompt groups findings by rule and includes the rule documentation.
  • VS Code extension 0.5.0 (attached).

Full changelog: https://github.com/sabahattink/codediag/blob/main/CHANGELOG.md

v0.6.0 — Deep Scan

Choose a tag to compare

@sabahattink sabahattink released this 29 Oct 20:18
de87d9b

Deep Scan: CodeDiag now covers Fastify, finds JWT and session misconfiguration, template injection, prototype pollution, and secrets outside source code. It can compare two scans or limit a scan to the files a branch changes.

npx @sabahattink/codediag@0.6.0 scan . --compare previous.json
npx @sabahattink/codediag@0.6.0 scan . --changed-since origin/main

Fastify

The API Health analyzer now reads Fastify apps:

  • routes from fastify.get() and fastify.route(), including routes inside register()-ed plugins and fastify-plugin plugins
  • onRequest, preParsing, preValidation, and preHandler auth hooks on the route or its encapsulation context
  • body schemas on mutating routes
  • setErrorHandler
  • health endpoints

There are four new rules: no-fastify-routes, missing-auth-hook, missing-route-schema, and missing-error-handler.

New security rules

  • jwt-none-algorithm (critical): algorithms: ['none'], algorithm: 'none', or jose's UnsecuredJWT
  • jwt-expiration-ignored: ignoreExpiration: true
  • insecure-cookie: session and token cookies without httpOnly and secure, and session middleware that turns either flag off
  • server-side-template-injection (critical): request data compiled as an EJS, Pug, Handlebars, Nunjucks, Eta, doT, or lodash template
  • prototype-pollution: target[a][b] = value with keys from request data (critical), and recursive merges without a __proto__ guard (warning)
  • dynamic-command-execution now also covers spawn() and execFile() with shell: true

Secrets beyond source code

hardcoded-secret now scans these files for provider tokens and for long, high-entropy values of secret-like keys:

  • JSON, YAML, TOML, INI, XML, and properties files
  • Dockerfiles
  • .npmrc and .yarnrc

The new committed-env-secret rule reports secrets in .env files that Git tracks. Ignored .env files are never read, and no report includes a secret's value.

Compare scans, or scan only what changed

  • --compare <report.json> shows score and per-analyzer deltas since an earlier JSON report, plus new findings (NEW, isNew) and fixed findings. It works in every output format; SARIF results get baselineState.
  • --changed-since <revision> reports and scores only the findings in files changed since a Git revision. That includes commits since the merge base, staged and unstaged edits, and untracked files.

Redesigned HTML report and project page

The HTML report adds:

  • a score gauge
  • analyzer weights and deltas
  • a change panel and a scope banner
  • search and a "New" filter
  • rule links and print styles

It still loads nothing from the network.

The project page was redesigned as well.

VS Code extension 0.4.0

Quick fixes on each problem suppress the rule on that line or in that file (you type the reason), or open the rule's documentation. The .vsix is attached to this release.

Known limitations

  • Fastify plugins loaded with @fastify/autoload are not followed yet.
  • Fastify auth and validation are recognized by naming, as with Express.

Rules: 70 → 80 · Full changelog: https://github.com/sabahattink/codediag/blob/main/CHANGELOG.md

v0.5.0 — Pull Request Comments

Choose a tag to compare

@sabahattink sabahattink released this 05 Oct 02:41
ded75b8

Pull request comments: CodeDiag now keeps one comment on each pull request with the score and the findings in the files that pull request changes.

permissions:
  contents: read
  pull-requests: write

jobs:
  codediag:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: sabahattink/codediag@v0
        with:
          threshold: 80
          comment: true

What the comment shows

  • ✅ or ❌: the score and grade against your threshold.
  • The change since the previous push, such as ▲ +3 since the last run.
  • The analyzer table.
  • Findings in the files this pull request adds or modifies. Critical findings come first, and each rule links to its documentation.
  • A count of findings elsewhere in the project, plus suppressed and baseline findings.

Every push updates the same comment, so the pull request never collects duplicates.

Safe by default

  • comment is off unless you set it to true.
  • Runs outside a pull request skip the comment.
  • If the comment can't be written (for example, a fork's read-only token), the Action logs a warning. The scan result, outputs, and threshold gate work as before.
  • No new dependencies. The comment uses the workflow's GITHUB_TOKEN through the REST API.

See the GitHub Action guide.

Full changelog: https://github.com/sabahattink/codediag/blob/main/CHANGELOG.md