Repository navigation
CodeDiag 0.10 "Reach" - #43
Merged
Merged
Conversation
…th.js middleware
- Hono: auth middleware registered before app.use(path, trpcServer())
for a matching path, including through app.route() and earlier
arguments of the same use(), protects the procedures; Hono's own
path matching decides, so use("/") no longer counts.
- Fastify: an auth hook on the context that registers fastifyTRPCPlugin,
an ancestor, or a fastify-plugin sharing one of them.
- Next.js middleware is run for an anonymous request to the tRPC path:
pathname comparisons and identity checks in if statements are decided,
so a guard scoped to /dashboard no longer counts. Auth.js v5 `auth` as
middleware is judged by its authorized callback (falsy redirects), and
auth(fn) by fn, where only a Response from authorized stops the request.
- Every adapter must sit behind a perimeter, not just the first kind found.
- Re-exports and destructured exports resolve across files.
The Next.js analyzer counted any middleware mentioning auth, session, or Clerk as protecting every API route. Middleware (and Next.js 16's proxy) is now evaluated for an anonymous request to each route path with the evaluator the tRPC perimeter uses: the matcher, path-scoped guards, next-auth, Clerk's protect(), Auth.js authorized callbacks, and helpers returned from the middleware such as Supabase's updateSession(). clerkMiddleware() alone no longer protects routes, matching Clerk's default of public routes. runtimeSources() and moduleIndex() move to the shared module index.
pnpm audits the whole workspace lock file from any package, so every package of a pnpm workspace ran the same audit and reported every other package's vulnerabilities as its own. Packages under a shared pnpm lock file now run one audit at the lock file (one prefetch job, one cache entry) and report only the advisories whose paths start at their importer (packages__api>lodash). npm and Yarn already audit the workspace they run in and are unchanged. The on-disk cache keeps the per-package split.
Adds the react-router framework id for React Router v7 framework mode and Remix v2. Detection requires a framework-mode package (@react-router/dev, node, serve, express, ...) next to react-router, a Remix package other than @remix-run/router, or an app/routes.ts that imports @react-router/dev/routes; react-router or react-router-dom alone is library mode. It runs after Next.js and before Fastify, Express, and Hono, because these apps often run on Express. Routes come from app/routes.ts (route, index, layout, prefix, plain entries, and flatRoutes() with rootDirectory and ignoredRouteFiles, read statically) or the flat file convention under app/routes, with appDirectory taken from the framework config. A route config that cannot be read statically, such as remixRoutesOptionAdapter with remix-flat-routes, leaves API Health not applicable instead of reporting missing routes. Rules: - missing-react-router-auth: an action with no auth check of its own (also two project calls deep) and no authenticating middleware on its route or a parent route. Sign-in, sign-up, and sign-out actions are exempt. - react-router-loader-auth-only: an action or loader whose only protection is a loader's auth check, which does not run before an action and runs in parallel with child loaders. Loader findings have medium confidence. - missing-react-router-validation: an action that reads request.formData() or request.json() without a schema parse or value checks. - no-react-router-routes: the framework is installed but no route modules exist. The realistic fixture is a routes.ts app with a middleware perimeter, Conform and Zod validation, a session-checked JSON resource route, and a health route; the defects fixture is a Remix v2 flat-routes app.
SvelteKit's cookies.set() defaults httpOnly and secure to true, so a session cookie set without those options on a request event's cookies in a SvelteKit module is not insecure. Explicit false is still reported.
createTRPCHandle() from trpc-sveltekit serves a router from the SvelteKit handle hook. Files importing it count as adapter files, and a createContext passed to it that rejects anonymous callers is a perimeter. The package's client export does not make a file an adapter.
Detects SvelteKit through @sveltejs/kit or a kit svelte.config, ahead of Express, Fastify, Hono, and tRPC, which a SvelteKit app may also use. +server handlers and +page.server form actions are the endpoints, named by their route without groups. New rules: - missing-sveltekit-auth: a mutating handler or action is neither guarded by the handle hook for its path or route id (sequence() parts and project imports followed, conditions evaluated per route) nor rejects anonymous callers itself or through helpers two calls deep. An auth check only in a layout or page load is named in the message, since actions run before loads and +server handlers without layouts. - missing-sveltekit-validation: a body read without a schema parse or a 400/422 check of the body. - sveltekit-csrf-disabled: kit.csrf.checkOrigin false or '*' in kit.csrf.trustedOrigins. - no-sveltekit-endpoints: +server files without handlers. Sign-in flows and handlers that forward the request to another router are not judged. tRPC procedures resolve $lib imports in SvelteKit apps.
# Conflicts: # dist/action.cjs # docs/rules.md # src/analyzers/trpc-api.ts # src/analyzers/trpc-perimeter.ts # src/detectors/stack-detector.ts # tests/benchmark.test.ts
…eal apps Scanning the Remix indie-stack, Epic Stack, and Lucia's SvelteKit example turned up critical findings for ordinary sign-up code: - plaintext-password-comparison now looks at equality expressions: a stored and a supplied password compared as values. typeof and length checks, comparisons with constants, and password !== confirmPassword are validation. - password-hashing-not-detected needs a write whose data holds the password as it came in (shorthand, a variable, or a property), not any create/update call in a file that mentions passwords; helpers such as getPasswordHash() count as hashing. - hardcoded-secret skips "Password is required"-style messages, placeholders, and password fixtures in test files; provider tokens in tests are still reported. - SHA-1 for the Pwned Passwords range API is not a weak password hash. - MOCK_ values are placeholders in committed .env examples. Security scores: indie-stack 3 -> 78, Epic Stack 0 -> 72, Lucia 53 -> 100, with no critical findings left in any of them.
Contributor
✅ CodeDiag: 95/100 (A+)no change since the last run · threshold 0
No findings in the files this pull request changes. Not listed: 2 findings elsewhere in the project. Scanned by CodeDiag · updated on every push |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
CodeDiag 0.10 "Reach": SvelteKit and React Router/Remix API Health, Next.js middleware judged per route, tRPC perimeters for Hono, Fastify, and Auth.js, one pnpm audit per workspace lock file, and an end to critical password and secret false positives on real apps.
Changes
src/analyzers/sveltekit-*.ts):+serverendpoints and form actions; auth from thehandlehook (throughsequence(), path and route id guards, and helpers) or in the handler. New rules:missing-sveltekit-auth(with a note when the only check sits in a layoutload),missing-sveltekit-validation,sveltekit-csrf-disabled, andno-sveltekit-endpoints.trpc-sveltekithandles count as tRPC adapters, andinsecure-cookiehonorscookies.set()defaults.src/analyzers/react-router-*.ts): actions and loaders fromapp/routes.tsor flat-route files, resource routes, re-exports, and routemiddleware. New rules:missing-react-router-auth,react-router-loader-auth-only,missing-react-router-validation, andno-react-router-routes.src/analyzers/next-middleware.ts): evaluated for an anonymous request to each route path, covering the matcher, pathname and identity conditions, next-auth, Clerkprotect(), Auth.jsauthorized, and returned helpers such as Supabase'supdateSession(). This replaces the keyword match that let any auth-flavored middleware protect every route.trpcServer()mounts and FastifyfastifyTRPCPluginregistrations are placed by each framework's own middleware and hook model. Auth.js v5 middleware is judged as Auth.js runs it. Every adapter must be covered.plaintext-password-comparisonandpassword-hashing-not-detectednow look at the syntax tree.hardcoded-secretskips messages, placeholders, and test fixtures.MOCK_values count as placeholders.export { auth as middleware } from "./auth") and destructured exports now resolve across files.Verification
npm run check:bundle:checkis clean;Real apps, scanned with
--no-auditand compared with 0.8.0/0.9 behavior:/apiNo critical finding is left in any of them.
A real pnpm workspace: lodash advisories appear only on the package that depends on lodash, and the audit runs once.