Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
b8d6ace
chore: set changesets baseBranch to develop
drbarzaga Mar 14, 2026
4190377
chore: update CI workflow permissions for GitHub Actions (#23)
drbarzaga Mar 14, 2026
1e90bd1
chore: release @route-auditor/cli@0.1.1 (#24)
drbarzaga Mar 14, 2026
991f619
feat: add GitHub Action (composite) for route-auditor (#26)
drbarzaga Mar 14, 2026
c92e964
docs: fix README table formatting (#27)
drbarzaga Mar 14, 2026
e39a33f
Fix/shared bundled (#29)
drbarzaga Mar 14, 2026
f5fbb30
Merge branch 'main' into develop
drbarzaga Mar 14, 2026
f6c4444
fix: replace createRequire(import.meta.url) with build-time constant …
drbarzaga Mar 14, 2026
f09e919
chore: merge main into develop, resolve version conflicts
drbarzaga Mar 14, 2026
fe7c09b
Merge branch 'main' of github.com:ayaxsoft/route-auditor into develop
drbarzaga Mar 14, 2026
1096b84
ci: auto-sync develop with main after every merge
drbarzaga Mar 14, 2026
642085d
Merge remote-tracking branch 'origin/main' into develop
github-actions[bot] Mar 14, 2026
968af12
Merge remote-tracking branch 'origin/main' into develop
github-actions[bot] Mar 14, 2026
4b32f02
Merge remote-tracking branch 'origin/main' into develop
github-actions[bot] Mar 14, 2026
6003ce3
docs: update readme with ci steps (#38)
drbarzaga Mar 14, 2026
f1087ce
Merge remote-tracking branch 'origin/main' into develop
github-actions[bot] Mar 14, 2026
9ff2bc7
docs: update variable naming examples in AGENTS.md (#40)
drbarzaga Mar 14, 2026
cf80901
docs: update repository URL in README.md (#41)
drbarzaga Mar 15, 2026
2099970
fix: Agent rules compilance (#42)
drbarzaga Mar 15, 2026
f07dae3
feat: security rules and rules command (#45)
drbarzaga Mar 15, 2026
b929e57
docs: update README and CLI documentation for improved clarity (#46)
drbarzaga Mar 15, 2026
dc3f9aa
chore: sync main into develop (#49)
drbarzaga Mar 15, 2026
676cfe8
feat: add landing page for route-auditor web package (#50)
drbarzaga Mar 16, 2026
3ad0c30
chore: sync main into develop (#52)
drbarzaga Mar 16, 2026
5a2af6d
chore: sync main into develop (resolve lockfile) (#54)
drbarzaga Mar 16, 2026
cb93571
Chore/update dev (#55)
drbarzaga Mar 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .changeset/common-peaches-appear.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
'@route-auditor/cli': minor
---

feat: add security rules, rules management command, and test coverage

- Add 4 new audit rules: insecure cookies (RW-COOKIE-001), missing webhook
verification (RW-WEBHOOK-001), path traversal (RW-PATH-001), and hardcoded
secret detection (RW-SECRET-001)
- Add `rules` CLI command to list, enable, and disable rules interactively
- Fix audit command config resolution to fall back to cwd when config not
found in projectRoot
5 changes: 5 additions & 0 deletions .changeset/fix-sarif-cjs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@route-auditor/cli': patch
---

Fix crash when running CLI via npx — replace `createRequire(import.meta.url)` with a build-time constant injected by tsup, which works in both CJS and ESM bundles.
5 changes: 5 additions & 0 deletions .changeset/real-bugs-smash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@route-auditor/cli': patch
---

Fix code style violations per AGENTS.md rules
3 changes: 1 addition & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
- If the code is a hack (like a setTimeout or potentially confusing code), it must be prefixed with // HACK: reason for hack
- MUST: Use kebab-case for files
- MUST: Use descriptive names for variables (avoid shorthands, or 1-2 character names).
- Example: for .map(), you can use `innerX` instead of `x`
- Example: instead of `moved` use `didPositionChange`
- Example: for .map(), you can use `index` instead of `x`
- MUST: Frequently re-evaluate and refactor variable names to be more accurate and descriptive.
- MUST: Do not type cast ("as") unless absolutely necessary
- MUST: Remove unused code and don't repeat yourself.
Expand Down
84 changes: 53 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,69 @@

Catch security issues in your Next.js routes before they reach production.

## Installation
Scans App Router, Pages Router, and API Routes — detecting missing authentication, CSRF gaps, permissive CORS, hardcoded secrets, and more. Stack-aware: fix suggestions are tailored to your detected auth library, validation library, and rate-limiting solution.

```bash
npm install -g @route-auditor/cli
```

## Usage
## Quick Start

```bash
route-auditor audit [directory]
npx @route-auditor/cli audit .
```

```
⚡ route-auditor
Audit Next.js routes for security issues.

✔ Scanned 34 routes in 8ms
[HIGH] Unprotected API Route · 3 routes
OWASP A01:2021 – Broken Access Control

[HIGH] Unprotected API Route 3 routes
A01:2021 – Broken Access Control

→ /api/users app/api/users/route.ts
→ /api/posts/[id] app/api/posts/[id]/route.ts
→ /api/users app/api/users/route.ts
→ /api/posts/[id] app/api/posts/[id]/route.ts

Fix: Use getServerSession(authOptions) to verify the session. (low effort)

85 / 100 Good
█████████████████████████████████░░░░░░░

3 vulnerabilities across 34 routes in 0.0s
3 vulnerabilities across 34 routes in 0.0s
```

## Options

| Option | Description | Default |
| ------------------------ | --------------------------------------------------------------------- | --------- |
| `-o, --output <format>` | Output format: `console`, `json`, `sarif` | `console` |
| `-s, --severity <level>` | Minimum severity: `critical`, `high`, `medium`, `low`, `info` | `info` |
| `--fail-on <level>` | Exit with code 1 if vulnerabilities at this level or higher are found | — |
| `--file <path>` | Write output to file instead of stdout | — |
| `--config <path>` | Path to `route-auditor.config.json` | — |
## Commands

| Command | Description |
| --------------- | --------------------------------------------------- |
| `audit [dir]` | Scan a Next.js project for security vulnerabilities |
| `rules [dir]` | List all rules with their enabled/disabled status |
| `rules disable` | Interactively select rules to disable |
| `rules enable` | Interactively select rules to enable |
| `init` | Generate a `route-auditor.config.json` config file |
| `report <file>` | Re-render a saved JSON audit in any output format |

## Audit Options

| Option | Description | Default |
| ------------------------ | --------------------------------------------------------- | --------- |
| `-o, --output <format>` | Output format: `console`, `json`, `sarif` | `console` |
| `-s, --severity <level>` | Minimum severity: `critical` `high` `medium` `low` `info` | `info` |
| `--fail-on <level>` | Exit with code 1 if issues at this severity or higher | — |
| `--file <path>` | Write output to file instead of stdout | — |
| `--config <path>` | Path to `route-auditor.config.json` | — |

## Rules

| ID | Name | Severity | Description |
| ----------------- | ---------------------------- | -------- | --------------------------------------------------------- |
| `RW-AUTH-001` | Unprotected API Route | high | API route with no auth check |
| `RW-AUTH-002` | Missing CSRF Protection | high | Server Action with no CSRF guard |
| `RW-AUTH-003` | Unprotected Sensitive Page | medium | Admin/dashboard page with no auth check |
| `RW-CORS-001` | Permissive CORS Policy | high | Wildcard `Access-Control-Allow-Origin: *` |
| `RW-ENV-001` | Exposed Environment Variable | high | Sensitive env var leaked in a response |
| `RW-WEBHOOK-001` | Missing Webhook Verification | high | Webhook route with no signature verification |
| `RW-PATH-001` | Path Traversal | high | Filesystem operation using unvalidated user input |
| `RW-SECRET-001` | Hardcoded Secret | critical | API key or secret hardcoded in source code |
| `RW-RATE-001` | Missing Rate Limiting | medium | API route with no rate-limit (high on auth endpoints) |
| `RW-INPUT-001` | Missing Input Validation | medium | POST/PUT route that parses body without schema validation |
| `RW-REDIRECT-001` | Open Redirect | medium | `redirect()` called with unvalidated user-supplied URL |
| `RW-COOKIE-001` | Insecure Cookie | medium | Cookie set without `HttpOnly`, `Secure`, or `SameSite` |

## CI Integration

Expand Down Expand Up @@ -101,32 +123,32 @@ steps:
```bash
# Fail the pipeline if any high or critical vulnerabilities are found
route-auditor audit . --fail-on high
```

```bash
# Export a SARIF report for GitHub Code Scanning
route-auditor audit . --output sarif --file results.sarif
```

## Configuration

Run `route-auditor init` to generate a config file, or create `route-auditor.config.json` manually:

```json
{
"severity": "medium",
"failOn": "high",
"rules": {
"RW-AUTH-001": false
"RW-RATE-001": false
},
"ignore": ["app/api/health/**"]
"ignore": ["/api/health", "/api/public/*", "/api/internal/**"]
}
```

## Contributing
All rules are enabled by default. Set a rule to `false` to disable it, or use `route-auditor rules disable` to manage rules interactively.

Want to contribute? Check out the codebase and submit a PR.
## Contributing

```bash
git clone https://github.com/drbarzaga/route-auditor
git clone https://github.com/ayaxsoft/route-auditor
cd route-auditor
pnpm install
pnpm build
Expand All @@ -140,4 +162,4 @@ node packages/cli/dist/index.js audit /path/to/your/nextjs-project

## License

route-auditor is MIT-licensed open-source software.
MIT
2 changes: 1 addition & 1 deletion eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ export default tseslint.config(
},
},
{
ignores: ['**/dist/**', '**/node_modules/**'],
ignores: ['**/dist/**', '**/node_modules/**', '**/.next/**'],
},
)
22 changes: 22 additions & 0 deletions packages/cli/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
# @route-auditor/cli

## 0.2.0

### Minor Changes

- 6185758: feat: add security rules, rules management command, and test coverage
- Add 4 new audit rules: insecure cookies (RW-COOKIE-001), missing webhook
verification (RW-WEBHOOK-001), path traversal (RW-PATH-001), and hardcoded
secret detection (RW-SECRET-001)
- Add `rules` CLI command to list, enable, and disable rules interactively
- Fix audit command config resolution to fall back to cwd when config not
found in projectRoot

### Patch Changes

- 6185758: Fix code style violations per AGENTS.md rules

## 0.1.6

### Patch Changes

- 0586b29: Fix code style violations per AGENTS.md rules

## 0.1.5

### Patch Changes
Expand Down
68 changes: 34 additions & 34 deletions packages/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ route-auditor audit [directory]
⚡ route-auditor
Audit Next.js routes for security issues.

✔ Scanned 34 routes in 8ms

[HIGH] Unprotected API Route · 3 routes
OWASP A01:2021 – Broken Access Control

Expand All @@ -49,6 +47,9 @@ Audit Next.js routes for security issues.
| Command | Description |
| --------------- | --------------------------------------------------- |
| `audit [dir]` | Scan a Next.js project for security vulnerabilities |
| `rules [dir]` | List all rules with their enabled/disabled status |
| `rules disable` | Interactively select rules to disable |
| `rules enable` | Interactively select rules to enable |
| `init` | Generate a `route-auditor.config.json` config file |
| `report <file>` | Re-render a saved JSON audit in any output format |

Expand All @@ -62,18 +63,47 @@ Audit Next.js routes for security issues.
| `--file <path>` | Write output to file instead of stdout | — |
| `--config <path>` | Path to config file | — |

## Configuration

Run `route-auditor init` to generate a config file, or create `route-auditor.config.json` manually:

```json
{
"severity": "medium",
"failOn": "high",
"rules": {
"RW-RATE-001": false
},
"ignore": ["/api/health", "/api/public/*", "/api/internal/**"]
}
```

All rules are enabled by default. Set a rule to `false` to disable it, or use `route-auditor rules disable` to manage rules interactively.

### Ignore patterns

| Pattern | Matches |
| ------------------ | -------------------------------------------- |
| `/api/health` | Exact path only |
| `/api/public/*` | One level deep (e.g. `/api/public/ping`) |
| `/api/internal/**` | Any depth (e.g. `/api/internal/admin/users`) |

## Rules

| ID | Name | Severity | Description |
| ----------------- | ---------------------------- | -------- | --------------------------------------------------------- |
| `RW-AUTH-001` | Unprotected API Route | high | API route with no auth check |
| `RW-AUTH-002` | Missing CSRF Protection | high | Server Action with no CSRF guard |
| `RW-AUTH-003` | Unprotected Sensitive Page | medium | Admin/dashboard page with no auth check |
| `RW-RATE-001` | Missing Rate Limiting | medium | API route with no rate-limit (high on auth endpoints) |
| `RW-CORS-001` | Permissive CORS Policy | high | Wildcard `Access-Control-Allow-Origin: *` |
| `RW-INPUT-001` | Missing Input Validation | medium | POST/PUT route that parses body without schema validation |
| `RW-ENV-001` | Exposed Environment Variable | high | Sensitive env var leaked in a response |
| `RW-WEBHOOK-001` | Missing Webhook Verification | high | Webhook route with no signature verification |
| `RW-PATH-001` | Path Traversal | high | Filesystem operation using unvalidated user input |
| `RW-SECRET-001` | Hardcoded Secret | critical | API key or secret hardcoded in source code |
| `RW-RATE-001` | Missing Rate Limiting | medium | API route with no rate-limit (high on auth endpoints) |
| `RW-INPUT-001` | Missing Input Validation | medium | POST/PUT route that parses body without schema validation |
| `RW-REDIRECT-001` | Open Redirect | medium | `redirect()` called with unvalidated user-supplied URL |
| `RW-COOKIE-001` | Insecure Cookie | medium | Cookie set without `HttpOnly`, `Secure`, or `SameSite` |

## CI Integration

Expand Down Expand Up @@ -141,36 +171,6 @@ Export a SARIF report for GitHub Code Scanning:
route-auditor audit . --output sarif --file results.sarif
```

## Configuration

Run `route-auditor init` to generate a config file, or create `route-auditor.config.json` manually:

```json
{
"severity": "medium",
"failOn": "high",
"rules": {
"RW-AUTH-001": true,
"RW-AUTH-002": true,
"RW-AUTH-003": true,
"RW-RATE-001": true,
"RW-CORS-001": true,
"RW-INPUT-001": true,
"RW-ENV-001": true,
"RW-REDIRECT-001": true
},
"ignore": ["/api/health", "/api/public/*", "/api/internal/**"]
}
```

### Ignore patterns

| Pattern | Matches |
| ------------------ | -------------------------------------------- |
| `/api/health` | Exact path only |
| `/api/public/*` | One level deep (e.g. `/api/public/ping`) |
| `/api/internal/**` | Any depth (e.g. `/api/internal/admin/users`) |

## License

MIT
9 changes: 5 additions & 4 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@route-auditor/cli",
"version": "0.1.5",
"version": "0.2.0",
"description": "Security auditor for Next.js routes — App Router, Pages Router, API Routes",
"keywords": [
"nextjs",
Expand Down Expand Up @@ -33,11 +33,12 @@
"release": "pnpm build && npm publish --access public"
},
"dependencies": {
"commander": "latest",
"chalk": "latest",
"ora": "latest",
"@inquirer/prompts": "^8.3.0",
"boxen": "latest",
"chalk": "latest",
"commander": "latest",
"glob": "latest",
"ora": "latest",
"zod": "latest"
},
"devDependencies": {
Expand Down
Loading
Loading