UNPKG

ubon

Version:

Security scanner for AI-generated apps (Cursor, Lovable, Windsurf, v0). Catches hardcoded secrets, prompt injection, hallucinated imports, Server Actions / Edge runtime mistakes, and the vibe-coded vulnerabilities traditional linters miss.

854 lines (672 loc) 39 kB
## 3.2.3 — Idempotent release workflow — 2026-05-13 ### Fixed - Made GitHub release creation idempotent when a release already exists for the pushed tag. ## 3.2.2 — Release metadata sync — 2026-05-13 ### Fixed - Normalized package metadata so npm no longer rewrites the binary path or repository URL during publish. - Fixed the GitHub release workflow so it extracts release notes from both `## 3.2.2` and `## [3.2.2]` changelog header styles. - Runs Jest in-band for `npm test` so release verification is stable under local and CI worker load. ## 3.2.1 — README release notes fix — 2026-05-13 ### Fixed - Updated the README release section from the old v3.0.0 summary to the current v3.2.0 agent harness, MCP, validation, and release-gate features. - Updated the Cursor setup example to use `ubon agent install --cursor --write`. ## 3.2.0 — Agent harness and validation release — 2026-05-12 ### What this release is An additive minor release that makes Ubon easier to wire into AI-assisted development loops and harder to release without proof. It adds a unified agent harness installer, broader Cursor/Claude/Codex guidance, richer MCP and CLI contracts, and a validation harness that tests Ubon against itself and against deliberately faulty examples. ### Agent harness - Added `ubon agent install` for dry-run-first generation of Cursor, Claude, Codex, pre-commit, GitHub Actions, and `.gitignore` harness files. - Expanded Cursor hook templates across shell, MCP, file edit, prompt, stop, and compaction events. - Added agent-oriented docs: `START-HERE`, `AGENT-HARNESS`, `AGENT-SEMANTICS`, `PROGRAMMATIC`, `VALIDATION`, and `RELEASE`. ### Validation and release gates - Added `npm run validate:harness`, fixture benchmarks, CLI/MCP contract tests, and a deterministic fix/rescan loop. - Added faulty fixtures for AI routes, Next Server Actions, MCP config, hallucinated imports, and dangerous reusable agent commands. - Wired the validation harness into `npm run verify` and kept package dry-run verification in `npm run verify:release`. - Added `npm run eval:agent` as an opt-in live-agent evaluation path. ### CLI and MCP - Added `ubon changed`, `ubon verify`, `ubon review`, and `ubon rules list --json`. - Added presets for agent, CI, release, and local workflows. - Expanded MCP tools with changed-file options, `baseSha`, verification, status, rule catalog, and fix planning. - JSON/MCP agent output can now include source context for repair loops. ### Rules and hardening - Added agent configuration rules for unknown Cursor hook events, broad agent autonomy, and dangerous reusable commands. - Hardened Git shell execution by switching to argument-vector based calls and validating branch names. - Tightened dogfood behavior, suppressions, package contents, and scanner exclusions so Ubon can scan itself with 0 unsuppressed critical findings. ## 3.1.0 — AI-tool coverage: React patterns, agent settings, module hygiene — 2026-04-19 ### 🎯 What this release is An additive minor release that broadens coverage of the AI-generated stacks ubon gets pointed at: React anti-patterns, Next App Router server/client boundaries, module-level hygiene, and the meta-configuration dotfiles that Claude Code, Cursor, and Windsurf commit into repos. No breaking changes to 3.0.x behavior; every addition is a new rule or a false-positive gate on an existing one. ### 🧩 New rule packs - **React anti-patterns (`REACT001`–`REACT011`).** New `ReactPatternsScanner` catches the staple AI-generated hazards: `key={i}` with array index, `onClick={fn()}` invoking on render, state mutation before the setter, `useEffect` with `setInterval` / `fetch` and no cleanup, `useEffect(async () => …)`, eager state initializer, conditional hook call, `useRef(…).current = x` during render, and JWT / bearer tokens stored in `localStorage` / `sessionStorage`. - **Security extensions (`SEC021`–`SEC031`).** Error stack leaked to the response body, silent `.catch(() => [])` stubs, weak crypto (`md5` / `sha1`) over credential-named variables, `Math.random()` for tokens / sessionIds, open redirect from user input, shell injection via `child_process.exec`, unchecked `fs.readFile(path.join(…))`, JWT tokens persisted in web storage, webhook handlers that never verify an inbound signature (`SEC029`), SSRF via `fetch(userUrl)` inside a route handler (`SEC030`), and timing-unsafe credential comparisons with `===` (`SEC031`). - **Next App Router boundaries (`NEXT220`–`NEXT225`).** `typeof window` inside an async server component, Client Component importing server-only modules (`fs`, `crypto`, `better-sqlite3`, Prisma…), Server Component importing client state libs (`zustand`, `jotai`, `recoil`, `valtio`), `route.ts` exporting `default` instead of named verbs, `<a href>` for internal routes where `next/link` exists, and `<form method="POST">` without a Server Action wiring. - **Module-level hygiene (`MOD001`–`MOD004`).** Side-effect calls at module top level, `async` functions without any `await`, `Promise.all([…]).catch(() => stub)` shrug-on-error, and the `: any` explosion (≥3 in one file; detailed-only). - **Agent / Claude Code tooling (`CC001`–`CC008`).** New `AgentSettingsScanner` walks `.claude/`, `.cursor/`, `.windsurf/`, `.mcp.json`, `CLAUDE.md`, `.cursorrules`, `.windsurfrules`, and friends. Flags literal secrets in settings / MCP env blocks, hooks that `rm -rf $VAR` unquoted, hooks that shell out to untrusted domains, inline secrets in agent memory / prompt files, and prompt-injection markers embedded in committed agent docs. ### 🧠 False-positive killers - **`NEXT*` rules gate on a detected Next.js project.** A Vite+React SPA with `src/pages/api/…` no longer spuriously lights up `NEXT209` / `NEXT217`; the framework and security scanners both read `package.json` once per scan and look for a `next` dependency or a `next.config.*` on disk before emitting App Router findings. - **`SEC023` sees credential context even without a direct target.** `return createHash('md5').update(password).digest('hex')` now fires via an enclosing-function parameter check, not just a direct variable assignment. - **`SEC021` catches `JSON.stringify({ stack: err.stack })`** in addition to `res.json` / `c.json` / `.send()`. - **`--detailed` and `--json` correctly propagate from CLI to core.** Previously low-confidence findings stayed filtered under `--json --detailed` because the flag wasn't threaded through `buildScanOptions`. ### 🧪 Fixture fleet Seven eval fixtures live out-of-tree under `~/Downloads/code/my-projects/test/buggy-*/`, one each for Next 15 + SQLite, Vite + React 18, Astro 4 + SSR, Lovable-style Next + Supabase, Claude Code / Cursor dotfile leaks, v0-style shadcn Server Actions, and a tricky T3-stack (`buggy-trpc-ai`: Next 15 + tRPC + Prisma + NextAuth + OpenAI) that stresses multi-file taint flows — SSRF via `fetch(userUrl)`, webhook handlers with no signature verification, timing-unsafe password compares, path traversal via form-data filenames, `NEXT_PUBLIC_` env used in auth gates, and a fake markdown sanitizer feeding `dangerouslySetInnerHTML`. Each ships a `BUGS.md` enumerating the planted bugs and the rule IDs expected to fire. `scripts/run-fixture-suite.sh` scans them all and prints a rule-ID histogram per fixture. An eighth fixture (`buggy-remix-ai`) targets Remix v2 + Vercel AI SDK + Drizzle + Resend + Upstash. Added detectors and gates so its planted bugs are caught: - **Remix + SvelteKit route detection.** `isRouteFile` now matches `app/routes/*.tsx` / `app/routes/*.ts` and `+server.ts|js|mjs`, so `SEC029` (missing webhook signature) and `SEC030` (SSRF) fire on Remix and SvelteKit endpoints, not just Next.js. - **`SEC026` through `promisify(exec)` aliases and named imports.** Tracks `const pexec = promisify(exec)` and `import { exec } from 'child_process'`; the bare-identifier call `pexec(cmd)` / `exec(cmd)` with a tainted arg is now flagged, matching how AI SDK "shell" tools are typically wired. - **`SEC027` on direct `fs.readFile` / `writeFile` sinks.** Not just `path.join(userInput)` — a tool callback like `execute: async ({ path }) => readFile(path, 'utf-8')` is now treated as arbitrary read/write. Gated to files that handle request input or import an AI SDK (`ai`, `@ai-sdk/*`, `@anthropic-ai/sdk`). - **One-hop taint through local bindings.** `const next = searchParams.get('next'); redirect(next)` now fires `SEC025`; `const target = url.searchParams.get('url'); fetch(target)` fires `SEC030`. A per-file pre-pass collects locals whose initializers mention a request-shaped identifier and feeds them into `callContainsUserInput`. - **Remix `action` exports recognized for `SEC029`.** Previously only `POST` / `default` exports triggered the "webhook with no signature verify" heuristic; Remix's `export async function action` now does. ### 🧠 False-positive killers (late additions) - **`coverage/`, `dist/`, `build/`, `out/`, `.ubon/` excluded by default.** Scanning a project's own Jest coverage HTML produced 30k+ spurious `A11Y005` findings on the generated lcov report. These directories now join the default ignore list alongside `.next`, `.turbo`, etc. - **`SEC025` only treats `router.push` / `history.replace` as navigation.** A bare `.push()` / `.replace()` on arbitrary receivers (`arr.push(x)`, `results.push(...)`) no longer fires — the receiver name must look like a router / history / navigation object. - **`SEC026` skips SQL-client `.exec(...)` calls.** `db.exec(\`INSERT … '${body.title}'\`)` is a SQL sink (SEC020 catches it), not a shell. Receivers named `db`, `knex`, `pool`, `conn`, `prisma`, `drizzle`, `sqlite`, etc., are excluded from SEC026. - **`SEC031` requires an operand to be credential-named.** The prior "context-nearby" heuristic matched `Token` as a substring of `EqualsEqualsEqualsToken` / `PlusToken`, lighting up every `===` inside TypeScript AST code. Now one side of the comparison must itself be `password`, `authToken`, `sessionId`, `apiKey`, `hash`, or a similar tight credential name. - **`SEC024` requires a tight credential-shaped target.** `const sessionsPerDay = Math.random()` and `session_type = Math.random()` no longer fire; the target must be an exact credential name (`token`, `sessionId`, `apiKey`, …) or `<anything>Id`. - **`NEXT201` / `NEXT202` gated on a real Next.js project.** Remix also uses `app/`; previously its projects always surfaced a spurious "missing `app/not-found.tsx`". ### 🧾 Tests - New `src/__tests__/fixture-suite-3.1.test.ts` — 21 integration tests covering the new scanners + SEC027/SEC028/SEC029/SEC030/SEC031 and MOD001 on inline fixtures. - Total test count: **214** (up from 193). ## 3.0.2 — Quick wins: trust, noise, coverage — 2026-04-19 ### 🎯 What this release is A focused patch on top of 3.0.1 that tackles the three biggest failure modes from real-world scans: **false positives that erode trust**, **noise that drowns real findings**, and a **handful of high-ROI rules that should already exist**. No breaking changes, no config migration, drop-in upgrade. ### 🧠 False-positive killers - **`tsconfig.json` path-alias resolver**`VIBE001` (hallucinated import) no longer fires on `@/lib/db`, `~/components/Foo`, or any other import whose `tsconfig.json` `paths` / `baseUrl` entry points to a real file. Covers the common Next.js / Vite / shadcn scaffolds. New utility: `src/utils/tsconfig-resolver.ts` with a string-aware JSONC comment stripper. - **Cross-scanner dedup** at the orchestrator. Previously `SEC017` (`dangerouslySetInnerHTML`) could fire twice per site from two passes. Findings are now deduplicated by `(ruleId, file, line)`, keeping the highest-confidence emitter. ### 🤫 Noise reduction - **`OSV001` grouped per package.** A single `next@15.0.0` no longer produces 15 identical HIGH findings — one grouped finding lists every advisory ID in the `match` field. Triage view stays readable. - **`JSNET001` debounced** to one warning per file (was: once per `fetch(` call). ### 🆕 New rules - **`SEC020`** — SQL sink called with template interpolation or string concatenation. AST-driven: matches `CallExpression` whose callee is `prepare` / `query` / `exec` / `execute` / `run` / `raw` / `$queryRawUnsafe` / `$executeRawUnsafe` / `unsafe` with a `TemplateExpression` (≥1 span) or a `+` `BinaryExpression`. Covers `better-sqlite3`, Prisma `$*Unsafe`, Drizzle `sql`, raw `pg`. - **`ENV008`** — Client-exposed env var carrying a database / service connection URL. Matches `NEXT_PUBLIC_` / `VITE_` / `PUBLIC_` / `EXPO_PUBLIC_` keys containing `URL` / `URI` / `DSN` / `HOST` / `CONN` / `ENDPOINT` / `DATABASE` whose value starts with `postgres://`, `mongodb://`, `redis://`, `mysql://`, `amqp://`, etc. - **`NEXT216`** — App Router page/layout types `params` or `searchParams` as a plain object. Next 15 passes a `Promise` here; the synchronous typing compiles but returns a thenable at runtime. - **`NEXT217`** — React hook used in a `.tsx` / `.jsx` file without a `'use client'` directive (fails the Next build, ships before `next dev` catches it). - **`NEXT218`**`reactStrictMode: false` in `next.config.*` (masks double-invocation bugs during dev). - **`NEXT219`** — Stale `experimental.serverActions: true` shape in `next.config.*` (ignored in Next 14/15). ### 🧪 Tests - 18 new Jest cases in `src/__tests__/quick-wins-3.0.2.test.ts` cover every new rule (positive + negative fixtures), the orchestrator-level dedup, and the tsconfig paths resolver. - Full suite: **193/193 green**. ### 🗺 Verification against a planted fixture On a purpose-built faulty Next 15 repo (`buggy-next/`, ~25 seeded vibe-coded bugs): | Change | Before 3.0.2 | After 3.0.2 | | --- | --- | --- | | Total findings | 30 | 20 | | `OSV001` (next CVEs) | 15 | 1 | | `SEC017` (dangerouslySetInnerHTML) | 4 | 2 | | `VIBE001` (`@/lib/db` false positive) | 2 | 0 | | `SEC020` (new: SQL injection) | 0 | 4 | | `ENV008` (new: `NEXT_PUBLIC_` URL) | 0 | 1 | | `NEXT216` / `217` / `218` / `219` (new) | 0 | 5 | ### Upgrade ``` npm install -g ubon@3.0.2 # or npx ubon@latest scan ``` --- ## 3.0.1 — `chmod +x` patch — 2026-04-19 ### 🐛 Critical fix - **`npx ubon` and the global bin were broken in 3.0.0.** The published tarball shipped `dist/cli.js` without the executable bit (`-rw-r--r--` instead of `-rwxr-xr-x`), so `sh: ubon: command not found` was returned for every install. The build script now runs `chmod +x dist/cli.js` after `tsc` so the bit is preserved through `npm pack`. Upgrade with `npm install -g ubon@3.0.1` or `npx ubon@latest`. `ubon@3.0.0` has been deprecated on npm. No source or rule changes — `3.0.1` is a packaging-only fix. --- ## 3.0.0 — Modernization & AI-Era Edition — 2026-04-18 ### 🎯 Major: AI-era detections, MCP server, Cursor hooks, deterministic output This is a focused, breaking release. The toolchain is modernized (Node 20+, ESLint 9 flat config, picocolors, glob 11, commander 13), the rule pack now covers what AI assistants actually ship in 2026, and Ubon can run as a Model Context Protocol server so the agent itself can call it. See [MIGRATION-v3.md](./MIGRATION-v3.md) for the upgrade checklist. ### ✨ New: AI-era rule pack (AI001–AI008) - **AI001** Hardcoded LLM API key (OpenAI/Anthropic/Google/Groq/etc.) - **AI002** Prompt injection sink (user input → system/user message) - **AI003** System prompt / model config leaked to client bundle - **AI004** Hardcoded vector-DB credential (Pinecone/Qdrant/Weaviate/Chroma) - **AI005** MCP server config with literal secret - **AI006** LLM tool/function handler with no auth or allowlist - **AI007** Streaming LLM endpoint missing auth + rate limit - **AI008** Unbounded LLM call (no `max_tokens`/`maxOutputTokens`) ### ✨ New: Modern framework rule pack - **NEXT212–215** Next 14/15 Server Actions (auth, validation, mass assignment, `use server` leaking into `use client`) - **EDGE001–003** Edge runtime: Node-only API misuse, Wrangler secret hygiene, top-level `process.env` reads in middleware - **SVELTE001–002** SvelteKit `+page.server` and `+server` checks - **ASTRO001** Astro endpoints missing validation - **REMIX001** Remix loaders / actions returning secrets - **HONO001** Hono CORS / rate-limit hints - **DRIZZLE001 / PRISMA001** raw SQL with user input ### ✨ New: AI-native integration - **`ubon mcp`** — Model Context Protocol server exposing `ubon.scan`, `ubon.check`, `ubon.explain`, `ubon.preview-fixes`, `ubon.apply-fixes`. Ships as an optional dependency (`@modelcontextprotocol/sdk`). See [docs/MCP.md](./docs/MCP.md). - **`ubon hooks install --cursor`** — drop-in `.cursor/hooks.json` plus shell scripts for `afterFileEdit` and `beforeSubmitPrompt`. - **LSP polish**`onDidChangeContent` debounce (500 ms), persistent cross-file results, `confidenceReason` in hover content. ### ✨ New: CLI ergonomics - **`ubon doctor`** — environment diagnostic (Node, git, optional deps) - **`--ndjson`** — one finding per line, ideal for streaming agents - **`--quiet`** — suppress banners and contextual guidance - **`--schema`** — print the JSON Schema for `--json` output and exit - **`--allow-config-js`** — gate `ubon.config.js` (executes user code) - **`ubon completion <bash|zsh|fish>`** — shell completion scripts - **Update notifier** — opt-out via `UBON_DISABLE_UPDATE_NOTIFIER=1` - **Homebrew formula**`scripts/homebrew/ubon.rb` for the upcoming tap ### ✨ New: Output guarantees - JSON output schema bumped to **`2.0.0`**, published at `docs/schema/ubon-finding.schema.json`. - JSON and NDJSON outputs are **byte-for-byte deterministic** across runs (sorted keys, stable severity order, undefined fields stripped). - SARIF: `partialFingerprints` is now emitted for every result; secret redaction goes through the centralized `redact()` utility shared with JSON / Markdown output. ### 🛠 Architecture - **Single source of truth for `RuleCategory`** in `src/rules/types.ts`. - **Reporters extracted** from the `UbonScan` orchestrator: `src/reporters/HumanReporter.ts`, `src/reporters/InteractiveReporter.ts`, `src/core/Posture.ts`. - **Profile registry** in `src/core/profiles.ts` — adding a profile is now a config change, not a new scanner class. - **Shared `FileSourceCache`** with `maxFileSize` (default 1 MiB) to avoid pathological regex backtracking on huge files. - **ReDoS audit** — bounded multi-line patterns (`[\s\S]{0,N}?`) in the security and Rails scanners. - **Crawler SSRF guard**`--crawl-start-url` restricted to localhost by default; opt out with `UBON_ALLOW_REMOTE_CRAWL=1`. ### 🧹 Repo hygiene - Removed `.tmp-cli-output.*`, `test-results.sarif`, empty `scripts/migrate-rules.js` and `src/rules/registry.ts`. - Coverage gates raised on critical utilities (`redact`, `sarif`, `Posture`). - New fixture-based integration tests for the AI scanner, framework scanner, NDJSON, schema dump, deterministic JSON, and a ReDoS regression test. - CI matrix updated to Node 20 / 22 / 24; `npm publish --provenance` on release; Dependabot config added. ### ⚠️ Breaking changes - **Node 20+** is required (Node 16 and 18 dropped). - **`ubon guide`** removed. - **JSON output schema** is `2.0.0`. Field set is unchanged but key ordering and the absence of `undefined` fields are now guaranteed. - **`ubon.config.js`** is no longer loaded by default; pass `--allow-config-js` or set `UBON_ALLOW_CONFIG_JS=1`. - **`chalk`** is no longer a runtime dependency (replaced by `picocolors`). User-visible output is unchanged. ### 🗑 Removed in v3.0.0 — scope cut v3 narrows Ubon's focus to modern JS/TS web stacks (Next.js, React, Vite, SvelteKit, Astro, Remix, Hono, Lovable). The following are gone: - **`--profile python`** and the entire `PythonSecurityScanner` (`PYSEC001``PYSEC005`, `PYNET001``PYNET002`, plus the `python-security-scanner.ts` source and tests). Use [Bandit](https://bandit.readthedocs.io/), [Semgrep](https://semgrep.dev), or [`pip-audit`](https://pypi.org/project/pip-audit/) for Python. - **`--profile rails`** and the `RailsSecurityScanner` (all `RAILS*` rules, `rails-security-scanner.ts`, and the Rails-faulty fixture app). Use [Brakeman](https://brakemanscanner.org). - **`--profile vue`** and the Vue-specific rule `VUE001` (v-html XSS), plus the `vue-faulty` fixture app. Use [`eslint-plugin-vue`](https://eslint.vuejs.org). - **`.py` auto-detection** in the `auto` profile. `auto` no longer glob-walks for Python files — it only flips between `lovable` and the JS baseline based on `package.json` and config files. - All scanner glob patterns, rule `fileTypes`, and Cursor `.cursor/rules/ubon.mdc` defaults that previously included `vue`, `py`, or `rb` were updated to `svelte` / `astro` / dropped. Selecting a removed profile via `--profile` exits with code `2` and prints the suggested replacement plus a link to [`MIGRATION-v3.md`](./MIGRATION-v3.md). ### 🪦 Deprecated (removal in v3.1) - `--crawl-internal` (Puppeteer crawler) — high-maintenance, low signal. - Loading `ubon.config.js` without `--allow-config-js` will hard-fail in v3.1; for now it errors with a clear migration message. ### 📚 Docs - Consolidated from 13 pages to 8: new [docs/INTEGRATIONS.md](./docs/INTEGRATIONS.md) (Cursor + Lovable + comparison) and [docs/ADVANCED.md](./docs/ADVANCED.md) (profiles + suppressions + baselines + output schemas + release policy). - New [MIGRATION-v3.md](./MIGRATION-v3.md) and rewritten README. --- ## 2.0.0 — The Vibe Code Edition — 2026-02-01 ### 🎯 Major: Vibe Code Detection Added comprehensive detection for common AI-generated code issues, plus architectural improvements and Cursor integration. #### New Rules: Vibe Code Detection (VIBE001-004) - **VIBE001**: Hallucinated imports — detects imports from packages not in package.json - **VIBE002**: Copy-paste artifacts — identifies repeated code blocks suggesting copy-paste without adaptation - **VIBE003**: Incomplete implementations — catches placeholder strings, "Not implemented" errors, TODO stubs - **VIBE004**: Orphaned exports — finds exported symbols never imported elsewhere #### New Scanner - **VibeScanner**: Cross-file analysis for AI-generated code patterns - Package.json dependency validation - Repeated block detection - Export/import graph analysis ### ✨ New Features - **Security Posture Score**: 0-100 score with visual bar in human output - **`--preview-fixes`**: Diff-like preview of auto-fixes before applying - **`confidenceReason`**: Every finding now explains its confidence level - **`ubon explain <rule>`**: New command to get detailed info about any rule - **Cursor Integration**: `docs/CURSOR.md` guide and `.cursor/rules/` for Cursor users - **All scanners exported**: Use any scanner programmatically via `import { VibeScanner } from 'ubon'` ### 🏗️ Architecture Improvements - **Modular Security Rules**: SEC001-SEC017 migrated to individual files in `src/rules/security/` - **SecurityScanner Refactor**: Now uses rule registry instead of hardcoded patterns - **BaseScanner Caching**: Result caching utilities available to all scanners - **CLI Refactor**: Shared logic extracted to `src/cli/shared.ts` - **All scanners exported**: 15 scanners now available for programmatic use - **Removed dead code**: Deleted empty `src/rules/registry.ts` ### 🐛 Bug Fixes - Watch mode now debounces rapid file changes to prevent overlapping scans - Scanners log file read errors when `--verbose` is enabled - `--no-result-cache` flag now available on `check` command - Fixed VIBE001 import detection regex for `from 'module'` syntax - Fixed LSP server TextDocumentSyncKind import ### 📚 Documentation - `docs/CURSOR.md`: Complete Cursor integration guide - `.cursor/rules/ubon-development.mdc`: Cursor rules for Ubon contributors - Updated `docs/RULES.md` with VIBE rules and confidence scale - Updated `docs/CLI.md` with all flags including `--preview-fixes`, `--watch`, `explain` command - Documented confidence scale (0.5-1.0) with explanations ### 🧪 Testing - New test suite for SEC001-SEC017 modular rules - Fixed regex lastIndex issues in security rules tests - VibeScanner test coverage ### Breaking Changes None. All changes are additive and backward-compatible. ### Notes - Vibe rules enabled by default in `auto` profile - Security posture score only appears in human output (JSON/SARIF unchanged) - Cursor integration is optional but recommended for AI-assisted development --- ## 1.2.0 — The Lovable Edition — 2025-10-13 ### 🎯 Major: Lovable App Support Added comprehensive security scanning specifically for Lovable-generated applications (React + Vite + Supabase + Tailwind stack). #### New Profile - **`--profile lovable`**: Specialized scanning for Lovable apps - **Auto-detection**: Automatically detects Lovable apps by stack signature (Vite + Supabase + React + Tailwind) - Optimized for React + Vite + Supabase + Tailwind CSS applications #### New Scanners & Rules **Lovable Supabase Scanner** (6 new rules): - **LOVABLE001**: Missing RLS Policy - validates actual RLS protection, not just existence - **LOVABLE002**: Exposed Supabase Keys - detects hardcoded URLs and anon keys - **LOVABLE003**: Anonymous Auth Without RLS - flags unprotected anonymous access - **LOVABLE004**: SQL Injection in Supabase Queries - detects unsafe string interpolation - **LOVABLE005**: Weak RLS Policy Patterns - identifies overly permissive policies - **LOVABLE006**: Supabase Storage Access Control - validates file upload security **Vite Scanner** (3 new rules): - **VITE001**: Client-Side Environment Variable Exposure - catches non-VITE_ prefixed vars - **VITE002**: Development-Only Code in Production - ensures proper fallbacks - **VITE003**: Unsafe Dynamic Imports - prevents path traversal in dynamic imports **Enhanced React Scanner**: - **TAILWIND001**: Dynamic className Injection - detects CSS injection via Tailwind ### ✨ Polish & Improvements - Added badges to README (npm version, downloads, coverage, license) - Added comprehensive comparison table (Ubon vs ESLint vs npm audit vs Lovable Scanner) - Fixed duplicate `prepublishOnly` in package.json - Updated all version references from 1.1.3 to 1.2.0 ### 📚 Documentation - Created `docs/LOVABLE.md` - Complete Lovable integration guide with examples - Updated `docs/RULES.md` with 10 new rules (detailed explanations + docs links) - Updated `docs/FEATURES.md` with Lovable profile documentation - Enhanced README with Lovable-specific examples and "What's New" section ### 🧪 Testing - New test suite: `lovable-scanner.test.ts` (20 tests, 100% coverage for all 6 rules) - New test suite: `vite-scanner.test.ts` (18 tests, ~78% coverage for all 3 rules) - Enhanced test suite: `react-security-scanner.test.ts` (17 tests, ~94% coverage) - Overall test coverage: ~47% → ~70% - All 88 tests passing ### 🎯 Target Audience This release is specifically designed for developers using: - **Lovable.dev** (primary focus) - Cursor, Windsurf, Replit (also supported) - Any React + Vite + Supabase stack ### Breaking Changes None. All changes are additive and backward-compatible. ### Notes - Lovable profile complements (not replaces) Lovable's built-in scanner - Auto-detection works seamlessly - just run `ubon scan` - Dashboard feature deferred to v1.3.0 ## 1.1.6 — 2025-09-18 ### Fixed - **Documentation Completeness**: Updated all documentation files to accurately reflect current capabilities - Added missing `ubon guide` command to CLI.md documentation - Updated FEATURES.md with contextual guidance and guide command features - Added missing Rails security rules (RAILS001-005) to RULES.md documentation - Ensured 100% accuracy between implemented features and their documentation ### Notes - This is a documentation accuracy release ensuring all docs reflect actual codebase capabilities - No functional changes - all existing features continue to work as expected ## 1.1.5 — 2025-09-18 ### Fixed - **Documentation Packaging**: Corrected npm package to include complete integration guide (GUIDE.md) and updated README - **GitHub Release**: Fixed v1.1.4 release to point to correct commit with all changes ### Notes - This is a documentation fix for v1.1.4 - no functional changes - All v1.1.4 features work correctly, this adds missing documentation files to npm package ## 1.1.4 — 2025-09-18 ### Added - **Smart Contextual Guidance**: Intelligent post-scan suggestions based on results - Suggests `--interactive` mode for critical issues - Recommends `--focus-critical` for high-severity findings - Points to `--apply-fixes` when auto-fixable issues found - Guides AI workflow with specific copy-paste instructions - **`ubon guide` Command**: New CLI command to access integration documentation - Shows guide file location and quick command examples - Provides essential workflows for developers and AI agents - **Enhanced Help Text**: Improved CLI descriptions promoting key features - Main help mentions guide command and interactive mode - Command descriptions highlight AI-friendly options ### Enhanced - **Integration Guide**: Renamed from `AI_AGENT_GUIDE.md` to `GUIDE.md` for universal appeal - Added real JSON/SARIF/CLI output examples - Enhanced troubleshooting section with common issues - Added framework-specific integration patterns - Comprehensive rule catalog with confidence levels - Performance optimization guidance for large codebases ### Technical - Smart guidance skips display in JSON mode and interactive mode - Guide command intelligently locates documentation file - All contextual suggestions use consistent lotus branding ### Notes - This release focuses on user experience improvements - Makes Ubon much more discoverable and intuitive for new users - Provides better integration patterns for AI assistants ## 1.0.0 — 2025-08-23 - ## 1.0.1 — 2025-08-23 ### Fixed - Avoid runtime crash when installed globally by lazily requiring TypeScript in AST scanner. If `typescript` is not present, AST-based checks are skipped gracefully instead of failing. - Move `typescript` to runtime dependencies to support global installs. Initial stable release. ### Profiles - React/Next.js - Vue.js - Python ### Security (JS/TS/Next) - Secrets and credentials: API keys (OpenAI/Stripe/AWS/GitHub), Supabase keys/URLs, DB URLs, hardcoded passwords, entropy-based detection (SEC018) - Code execution and injection: `eval()`, `dangerouslySetInnerHTML`, React.createElement injection (SEC019), dynamic import with user input (NEXT004) - Next.js SSR/API: secrets in `getServerSideProps/getStaticProps` (NEXT006), API route validation heuristic (NEXT003) - Logging: potential secrets printed to logs (LOG001) - Network hygiene: fetch/axios without timeout/AbortController (JSNET001); cookie flags (COOKIE001) - AST-assisted JS/TS analysis for higher precision on eval/innerHTML/env fallback/fetch ### Security (Python) - `exec`/`eval`, `subprocess(shell=true)`, unsafe `yaml.load`, `pickle`, `requests(verify=false)` - Framework settings: `DEBUG=True`, permissive `ALLOWED_HOSTS`; requests without timeout (PYNET001) ### Accessibility - Images without alt and missing width/height (A11Y001, A11Y006/007) - Non-semantic clicks on `<div>` or Vue `@click` without roles (A11Y004) - Next.js guidance: external `<img>` usage (NEXT005) ### Environment & configuration - `.env` hygiene: not ignored, secrets in `.env`, missing `.env.example` - Drift detection between `.env` and `.env.example` (ENV007) - Config via `ubon.config.(json|js)` and `package.json.ubon` - Baseline and suppressions with stable fingerprints (inline: `ubon-disable-file`, `ubon-disable-next-line RULEID`) - Changed-files mode and `--git-changed-since` ### Links & crawling - External link reachability via HTTP(S) HEAD with timeouts (LINK002) - Internal crawler (opt-in, Puppeteer) for broken internal links/routes (LINK003) ### Dependency & supply chain - OSV.dev advisories for npm and PyPI (OSV001) - Git history secret scanning (regex + entropy) ### DX & output - Deterministic, agent-friendly JSON (schemaVersion/toolVersion), redaction, and machine-actionable `fixEdits` - SARIF 2.1.0 output for GitHub code scanning - `--fast` mode to skip OSV, link checks, and crawler ### CLI - Core: `--json`, `--sarif`, `--output`, `--fail-on`, `--min-confidence`, `--enable-rule`, `--disable-rule`, `init` - Baseline: `--baseline`, `--update-baseline`, `--no-baseline` - Scope: `--changed-files`, `--git-changed-since`, `--git-history-depth` - Profiles: `--profile auto|react|next|vue|python` - Crawler: `--crawl-internal`, `--crawl-start-url`, `--crawl-depth`, `--crawl-timeout` - Fixes: `--fix-dry-run`, `--apply-fixes` ### Notes - External link checks are timeout-guarded; internal crawling remains opt-in. - Heuristics aim to minimize noise; tune with confidence thresholding, rule enable/disable, and baselines. ## 1.0.2 — 2025-08-23 ### Changed - CLI polish: lotus emoji branding in descriptions and consistent version read from package.json. ### Notes - Cosmetic/non-breaking update to improve CLI identity. ## 1.0.3 — 2025-08-23 ### Changed - CLI styling and badges refreshed; minor cosmetic updates. ### Notes - Cosmetic/non-breaking update; no behavior changes. ## 1.0.4 — 2025-08-24 ### Added - Human output triage header with severity-first summary (non-breaking; JSON/SARIF unchanged) - Focus filters for human output: `--focus-critical`, `--focus-security`, `--focus-new`, and `--detailed` ### Changed (non-disruptive) - SEC018 noise reduction: context/file-aware ignores (CSS/Tailwind/globs/data URIs/UUID), pattern-first detection for `sk-`/JWT/DB URLs/etc., higher entropy threshold - Runtime default minConfidence=0.8 for human runs (non-JSON) when not provided (does not change config or JSON/SARIF) ### Tests & Docs - Added tests covering SEC018 false positives and true positives - Updated CLI docs with new flags and examples This patch focuses on triage-first UX and noise reduction without changing schema or defaults that would break existing workflows. ## 1.1.0 — 2025-08-25 ### Added - Colorized, branded output with lotus (🪷) and `--color` flag - Result organization with `--group-by`, `--min-severity`, `--max-issues` - Code context (`--show-context`) and explanations (`--explain`) - Confidence display (`--show-confidence`) in human output - Inline suppressions: `// ubon-disable-next-line RULEID [reason]` with `--show-suppressed`/`--ignore-suppressed` - OSV caching (24h TTL) with `--clear-cache`, `--no-cache`, and `ubon cache` command - Next.js security rules: JWT in responses (NEXT007), missing security headers (NEXT008), unsafe redirects (NEXT009), permissive CORS (NEXT010), client env leaks (NEXT011) - CI gate: `--base-sha` (fail only on new issues vs base) - Watch mode: `--watch` (incremental re-scan; use with `--fast`) - Create PR: `--create-pr` after `--apply-fixes` - VS Code extension (MVP): diagnostics + quick fixes - Experimental Next.js routing/structure rules (NEXT201–NEXT209) ### Rails - Rails profile (experimental): SQLi in where, system/backticks, YAML.load, html_safe in ERB ### Autofixes (safe) - Accessibility: add `alt` to `<img>`, `aria-label` to `<input>`, add `role="button" tabIndex={0}` to clickable `<div>`, convert `<a>` without `href` to `<button>` - Security: redact secret-like tokens in `console.*` calls; add `HttpOnly; Secure` to JWT cookies - Env/config: remove hardcoded fallbacks from `process.env.X || '...'` - Networking: suggest `{ signal }` on `fetch(...)` (AbortController) ### Performance - Repeat scans ~30–40% faster when OSV cache is warm ### Docs - README streamlined with AI Assistants workflow; feature matrix added in `docs/FEATURES.md`; CLI cross-links. - P5 rules documented as experimental with enable/disable examples. ### Notes - All changes are non-breaking and gated behind flags; JSON/SARIF schema remains stable ## 1.1.1 — 2025-08-25 ### Changed - Default human run applies AI-friendly preset: enables show-context, explain, severity grouping, caps max-issues to 15 by default (overridable). `--ai-friendly` still forces JSON + the same human-friendly settings for agent use. - README: added TL;DR block at the top with quick install/run. - New flag: `--pr-comment` to emit a Markdown summary for PR reviews. ### Notes - Non-breaking; JSON/SARIF unchanged. ## 1.1.3 — 2025-08-29 ### Added - **Interactive Mode**: `--interactive` flag for step-by-step issue walkthrough with explanations, context, and fix options - **Beautiful CLI Color System**: Lotus-inspired severity bands with enhanced visual triage - Critical: Deep lotus red, High: Coral pink, Medium: Amber, Low: Lotus green - Consistent `🪷` lotus branding throughout all scanner completion messages - **Modular Rules Architecture**: New `/src/rules/` structure with category-based organization for better maintainability - **Development Scanner**: New DEV001-005 rules specifically for AI-generated code issues - DEV001: TODO/FIXME comments detection - DEV002: "Not implemented" stubs and placeholder functions - DEV003: Placeholder URLs in API endpoints (`localhost`, `example.com`) - DEV004: Hardcoded mock/example data in responses - DEV005: Empty returns or unimplemented functions ### Enhanced - **Triage Header**: Beautiful colored severity bands replace basic text output - **Success Messages**: Enhanced with lotus theming ("🪷 No issues found! Your app is blooming beautifully! ✨") - **Scanner Progress**: All completion messages now use `🪷` lotus emoji for consistent branding ### Technical - Made `printResults()` async to support interactive mode - Added new `ScanOptions.interactive` property - Enhanced `getSeverityBand()` method with lotus-inspired color palette - Backward compatibility maintained for all existing features ### Notes - Interactive mode provides guided issue resolution perfect for AI-assisted debugging - Development scanner addresses the "vibe-coded" app debugging crisis - All changes are non-breaking; JSON/SARIF output unchanged ## 1.1.2 — 2025-08-27 ### Added - Compact table output: `--format table` for skimmable terminal triage. - Per-file result cache for faster repeat scans (disable with `--no-result-cache`). - Experimental P5 rule: NEXT210 — detects server→client secret bleed via SSR props. ### Docs - CLI docs updated (format=table, result cache, pr-comment). - New `docs/COMPARISON.md` outlining Ubon vs ESLint vs npm audit.