Releases: CaspianTools/caspian-security
Release list
v10.6.1 — comprehensive User Guide
Documentation release.
Added
- docs/USER_GUIDE.md — a comprehensive user guide: installation, the standalone
caspianCLI (every subcommand, flags, exit codes, baselines, PR-scope), VS Code usage, AI-agent integration (CLAUDE.md snippet + MCP for Claude Code / Cursor / Antigravity / Claude Desktop / Cline), CI/CD, configuration, output formats, rule categories, troubleshooting, and a cheat sheet. - docs/user-guide.html — self-contained, styled HTML version.
- A mirrored User Guide page on the GitHub Wiki, linked from the sidebar and Home.
- Pointers to the guide from README and START_HERE.
Changed
- CLAUDE.md — new rule: any update must trigger a documentation update when relevant, keeping the Markdown guide, HTML guide, and wiki User Guide in sync.
Marketplace: https://marketplace.visualstudio.com/items?itemName=CaspianTools.caspian-security
v10.6.0 — unified caspian CLI + one-line AI-agent integration
Caspian goes anywhere. One unified caspian command turns the scanner into a robust standalone tool you can run from a normal PowerShell / cmd / bash terminal — no VS Code required — and makes it a one-line integration for any AI coding agent (Claude Code, Cursor, Antigravity, Claude Desktop, Cline). Nothing is ever written into your repositories; Caspian only emits text and config you choose to paste.
Added
- Unified
caspiancommand —caspian scan | git-history | check-updates | mcp | snippet | mcp-config. Install globally (npm i -g caspian-security→caspian scan .) or zero-install (npx -y caspian-security caspian scan .). Works in PowerShell, cmd, and bash. caspian snippet— prints a paste-ready CLAUDE.md / Cursor / Antigravity instruction block so any agent can run Caspian mid-task vianpx, with zero setup in the target repo.caspian mcp-config— prints the MCP server config with the correct path per client (Claude Code, Claude Desktop, Cursor, Antigravity, Cline).- Two VS Code commands — "Copy AI Agent Instructions" and "Copy MCP Server Config" (clipboard-only; never write into a repo).
Changed
- CLI entry points now export an
argv-taking function guarded byrequire.main === module, so the dispatcher reuses one implementation. Originalcaspian-scan/caspian-git-history-scan/caspian-check-updates/caspian-mcpbins are unchanged. - MCP docs now cover Claude Code (
.mcp.json/claude mcp add) and Antigravity in addition to Claude Desktop / Cursor / Cline.
Marketplace: https://marketplace.visualstudio.com/items?itemName=CaspianTools.caspian-security
v10.5.1 — maintenance release, lockfile refresh
Maintenance release — marketplace re-publish with refreshed package-lock.json. No functional changes from 10.5.0.
Changed
package-lock.jsonregenerated against currentnpm installto keep the lockfile aligned with the published version.
For the full feature set introduced in 10.5.0 (one-click quick-fix lightbulb for 13 mechanical remediations), see the v10.5.0 release notes.
v10.5.0 — one-click quick-fix lightbulb
[10.5.0] - 2026-04-21
The lightbulb release. Hover on a Caspian finding, press Ctrl+. (or click the yellow lightbulb), and get a deterministic one-click fix for the 13 most common mechanical remediations — no AI round-trip, no waiting on a consent dialog, no spend on provider tokens.
Added
- src/codeActionFixes.ts — pure-function fix registry. Each entry takes a minimal
DocumentView+ the issue's line/column and returns aFixResult(edits + title). Novscodeimport, fully unit-testable. - src/codeActionProvider.ts — thin
vscode.CodeActionProviderwrapper that convertsFixResults intovscode.CodeActionquick-fixes. Registered for every enabled language plusdockerfile,yaml,terraform, and glob patterns for**/Dockerfile/**/*.tf/**/*.tfvars/**/*.hcl/**/*.yaml. - 13 mechanical fixes across every major rule family:
- Kubernetes —
K8S001flipprivileged: true→false,K8S002removehostNetwork: trueline,K8S003removehostPID/hostIPC: trueline,K8S004fixrunAsUser: 0→runAsUser: 1000ORallowPrivilegeEscalation: true→false. - Terraform —
TF002flipacl = "public-read"to"private",TF004flippublicly_accessible = true→false. - JWT —
JWT002insert{ algorithms: ['RS256'] }as third arg tojwt.verify(token, key),JWT006removeignoreExpiration: trueor flipverify_exp=False→True. - Python deserialisation —
DESER003renameyaml.unsafe_load → yaml.safe_load,DESER004renameyaml.load( → yaml.safe_load((skips ifSafeLoaderalready specified). - TLS —
ENC004fliprejectUnauthorized: false→true. - Dockerfile —
DOCKER008comment-outHEALTHCHECK NONE(recoverable; doesn't delete). - CORS —
CORS001replaceorigin: '*'withorigin: false(reject by default; user adds allow-list after).
- Kubernetes —
- 21 unit tests (src/tests/codeActionFixes.test.ts) exercising every fix — happy path, shape-mismatch returns null, out-of-bounds tolerance, "already-safe" suppression.
Why deterministic text-only fixes
The existing Caspian Security: Fix Issue with AI command handles the ambiguous cases (which DOMPurify call? what's the right Zod schema?) and has a consent dialog for good reason. These 13 fixes are the cases where the right answer is unambiguous — privileged: true has exactly one correct remediation, and it's privileged: false. Showing a lightbulb cuts the friction to a single keystroke for the 80% of findings that don't need judgment.
How it shows up in VS Code
- Scan runs, diagnostic appears with the usual
[Category] RULE_CODE: messageformat. - VS Code displays a yellow lightbulb in the gutter; clicking it (or
Ctrl+.) lists the fix with a concrete title (Set privileged: false,Remove hostNetwork: true, etc.). - Applying triggers a
WorkspaceEdit— instant, reversible via undo. - The fix is marked
isPreferred, so "Apply quick fix" /Ctrl+.→ Enter selects it by default.
Changed
- Test suite: 989 → 1010 (+21). Rules unchanged at 295+.
- src/extension.ts activates the provider once via
registerCaspianCodeActionProvider(context, enabledLanguages).
Notes
- The provider is conservative: every fix returns null if the matched line's shape doesn't exactly fit the expected pattern. False "auto-fix" is worse than no auto-fix.
- The AI-fix path is untouched. Users still get
Caspian Security: Fix Issue with AIfor everything these mechanical fixes don't cover.
v10.4.0 — Model Context Protocol server
[10.4.0] - 2026-04-21
Caspian is now a Model Context Protocol server. Any MCP client — Claude Desktop, Cursor, Zed, Cline — can call scans directly from tool use. "Use Caspian to scan this repo" goes from four-step manual flow to one-line prompt.
Added
- MCP server (src/cli/mcpServer.ts) exposing four tools over stdio:
scan— workspace scan with optional severity filter and max-findings truncation; returns categorised summary + findings as JSON.scan_git_history— spawns the existing git-history scanner and parses its JSON output.list_rules— rule catalogue with optional category filter.explain_rule— full description + suggestion + context-awareness / file-pattern metadata for a given rule code.
- New bin entry
caspian-mcpalongside the existingcaspian-scan,caspian-git-history-scan,caspian-check-updates. Launched vianpx caspian-security caspian-mcpor globally. - src/scanRunner.ts — workspace-scan logic extracted so both the CLI and the MCP server share one implementation.
walkFiles(),resolveLanguage(),scanFile(), and a newrunWorkspaceScan()wrapper. No I/O concerns beyondfs.readFileSync— caller chooses the output format. - 12 new unit tests (src/tests/mcpServer.test.ts) exercising the four handlers + the dispatch layer directly. Smoke-verified end-to-end:
initialize+tools/listover real stdio returns the tool catalogue. - Runtime dep:
@modelcontextprotocol/sdk^1.29.0. First non-devDependency runtime dep on the project, but the SDK ships both ESM and CJS entries so it threads cleanly into our CommonJS build.
Changed
- BUILD.md §3c — Claude Desktop + Cursor wiring instructions with copy-pasteable
mcpServersconfig. - README.md Install section — adds the MCP block alongside VS Code, npm, and GitHub Actions paths.
- Test suite: 977 → 989 (+12 MCP handler tests). Rules unchanged at 295+.
Security notes
- The MCP server is stdio-only — no network port, no auth tokens, no telemetry.
- Each tool call validates the
pathargument exists and is a directory before scanning. - The
scan_git_historytool is guarded by a.gitdirectory check and respects the same 100 ms/file taint deadline and 3 s/file rule deadline as every other scan path.
v10.3.0 — PR-scope scanning with --changed-since
[10.3.0] - 2026-04-21
PR-scope scanning. Pair it with v10.1's baseline and your monorepo PR CI stops being a full-repo scan.
Added
--changed-since <ref>CLI flag. Restricts the scan to files that differ from the ref in a<ref>...HEADdiff. Three-dot semantics means "everything this branch adds since diverging from ", not "everything different from right now" — so newer commits on the base branch don't pollute the set.--diff-filter=dexcludes deletions (nothing to scan).- src/gitDiff.ts —
getChangedFilesSince(workspace, ref)shells out togitviaspawnSyncand returns a Set of absolute paths. Clear error messages for missing ref, non-git repo, or git-not-installed. - GitHub Action
changed-sinceinput — threads through to the CLI. Paired withactions/checkout@v4 fetch-depth: 0so the base ref resolves. - 4 new unit tests (src/tests/gitDiff.test.ts) covering: empty diff, absolute-path output, non-existent ref error, non-git-directory error. Shallow-clone tolerant.
Why three-dot diff
--changed-since origin/main under two-dot semantics (origin/main..HEAD) would give the same files as three-dot in the common case — but if origin/main has moved forward since this branch diverged, two-dot includes files on origin/main that this branch never touched. Three-dot (origin/main...HEAD) uses the merge-base, which is what PR review UIs show. Caspian follows the PR-review convention.
Example — monorepo CI workflow
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: Caspian-Explorer/caspian-security/.github/actions/scan@v10.3.0
with:
baseline: .caspian-baseline.json
changed-since: ${{ github.event.pull_request.base.sha }}
fail-on: errorResult: full-repo scans measured in minutes collapse to seconds on typical PRs. The baseline handles the legacy backlog; --changed-since handles the review velocity.
Changed
- CLI
--helptext documents--changed-since. - BUILD.md gains Section 3b — "PR-scope scanning with
--changed-since". - Test suite: 973 → 977 (+4 gitDiff). Rules unchanged at 295+.
v10.2.0 — npm distribution channel
[10.2.0] - 2026-04-21
Caspian is now installable from three registries: VS Code Marketplace, Open VSX, and npm. The same rule engine reaches every developer — IDE, CLI, CI — through the channel most natural for their workflow.
Added
- npm distribution. Same package, same name (
caspian-security), same source tree.npm install -g caspian-security/npx caspian-security caspian-scan ./npm install --save-dev caspian-security. No more "clone the repo first" friction for non-GitHub CI pipelines (GitLab, CircleCI, Jenkins, Drone, BuildKite all work out of the box). - Three
bincommands —caspian-scan(main SARIF scanner),caspian-git-history-scan(secret scanner for git log),caspian-check-updates(dependency audit). All three read the CLI shebang that's already present in source. filesfield scoped tightly — onlyout/, LICENSE, README, CHANGELOG, SECURITY, THREAT_MODEL, and icon ship to npm. No source tree, no tests, no.vsixartefacts.npm run publish:npmscript (runsnpm run compilefirst, thennpm publish --access public). Matches the existingpublish:vscode+publish:openvsxpattern so all three registries publish from the same compiled bits.
Changed
- BUILD.md publishing section — rewritten around a three-registry table. Each channel gets its own auth / publish walkthrough. Documents that
require('caspian-security')isn't supported (themainfield points at the VS Code extension entry which needsvscode); use the bin commands instead. - README.md — new "Install" section near the top covers VS Code / Open VSX / npm / GitHub Actions side by side. Overview copy updated to reflect the current scope (295+ rules, IaC + code, taint tracking, per-invocation consent default).
Notes
- Same rule engine, same SARIF, same baseline format across all three channels. The extension's diagnostics, the CLI's SARIF output, and the Action's uploaded results are indistinguishable once you've stripped the UI chrome.
- Publishing to npm requires a maintainer
npm login+ OTP. The script is in place; actually pushing to the registry is a one-time action the owner runs when ready.
v10.1.0 — baseline / suppression file support
[10.1.0] - 2026-04-21
The adoption-killer feature: baseline / suppression file support. Drop Caspian into any existing codebase without a big-bang remediation.
Added
- Baseline file support.
caspian-scan --baseline .caspian-baseline.jsonloads a per-file, per-rule count of known findings and suppresses them from the exit-code gate. Only NEW findings above the baseline counts fail the build.--update-baselineregenerates the file from the current scan. src/baseline.ts—loadBaseline,buildBaseline,writeBaseline,applyBaseline,normalisePath. Counts-based matching (no fingerprinting) so diffs are human-readable and the baseline auto-tightens as issues get fixed. Path-normalised so baselines survive Windows ↔ Linux CI.- GitHub Action
baselineinput. Dropbaseline: .caspian-baseline.jsoninto your workflow;.github/actions/scan/action.ymlthreads it through to the CLI. - 12 new unit tests under
src/__tests__/baseline.test.tscovering build, apply, normalisation, round-trip, and three flavours of load-error.
Why counts, not fingerprints
Fingerprints either need a line number (fragile; breaks on every edit) or a normalised-context hash (fragile for different reasons and opaque in diffs). Per-file / per-rule counts are human-readable, git-diff-friendly, and auto-tighten: fix one of three findings, the count drops on --update-baseline, and adding a new one fails the build.
Example
node out/cli/scan.js . --baseline .caspian-baseline.json --update-baseline
# (review + commit .caspian-baseline.json)
node out/cli/scan.js . --baseline .caspian-baseline.json --fail-on error
# → 0 new findings, exit 0Changed
- CLI help text documents
--baselineand--update-baseline. - BUILD.md gains a "Section 3a — adopting Caspian into an existing codebase" with the full workflow.
- Rule totals unchanged at 295+. Test suite: 961 → 973 (+12 baseline tests).
v10.0.0 — infrastructure scanning: Dockerfile, Terraform, Kubernetes
[10.0.0] - 2026-04-21
Caspian graduates from "code scanner" to "code + infrastructure scanner" — and earns its major-version bump.
The major-version marker reflects a new scanning domain. Everything Caspian did before is preserved and improved; we added a parallel surface (Dockerfile, Terraform/HCL, Kubernetes YAML) that's as thorough as the existing 9.x code rules.
Added — Infrastructure-as-code
- Dockerfile rules (
DOCKER001–DOCKER008).:latest/ unpinned base images, missing non-rootUSER, secrets baked intoENV/ARG/RUN,ADDfrom a URL,curl | sh, package-install without--no-install-recommends/ pinned versions,HEALTHCHECK NONE. Fires onDockerfile,Containerfile,*.dockerfile. - Terraform / HCL rules (
TF001–TF010).0.0.0.0/0ingress, public S3 ACLs / missing public-access blocks, wildcard IAMAction/Resource(HCL lowercase and JSON forms),publicly_accessible = trueRDS, missing at-rest encryption on S3 / EBS / RDS, hardcodedmaster_password, disabled CloudTrail,AdministratorAccessattached to task/function roles, HTTP-without-HTTPS-redirect load balancers, KMSkms:*to account root. Fires on.tf,.tfvars,.hcl. - Kubernetes manifest rules (
K8S001–K8S008).privileged: true,hostNetwork/hostPID/hostIPC: true,runAsUser: 0/allowPrivilegeEscalation: true,hostPathvolumes, dangerous Linux capabilities (SYS_ADMIN,NET_ADMIN,SYS_PTRACE,BPF), wildcard RBAC verbs / resources,LoadBalancerwithoutloadBalancerSourceRanges. Fires on*.yaml/*.yml; excludes GitHub Actions workflows anddocker-compose.yaml.
Added — Quality gate
- Vulnerable-corpus regression suite (
src/__tests__/vulnerableCorpus.test.ts+src/__tests__/fixtures/vulnerable-corpus/). Small synthetic fixture tree containing intentional vulnerabilities across every rule family. Each fixture has a minimum set of rule codes it MUST detect — any rule that stops firing breaks the build. Ratchet-style (new detections are fine; removed detections fail). No external repo downloads, CI-viable. - Caught two real regressions during development:
JWT002regex rejected string-literal secrets;TF003regex missed HCL's lowercaseactions/resources. Both fixed in the same commit that added the test.
Changed — CLI / file walker
- The CLI now scans
*.yaml,*.yml,*.tf,*.tfvars,*.hclby default, and special-cases filenamesDockerfile,Containerfile,dockerfile. Rules usefilePatterns.includeto scope per file type — Dockerfile rules don't fire on.tf, etc. - New
resolveLanguage()helper maps filename + extension to Caspian'slanguageIdfor downstream file-gated rules.
Stats
- Rule totals: 270+ → 295+. Test suite: 880 → 961 (+81). Two new test suites (
vulnerableCorpus, plus the 26 new rules contribute toredosGuard). - Lint clean, compile clean, self-scan strict-mode clean.
Upgrade notes
- No setting changes. No rule renames. Old code rules fire identically; new IaC rules only activate on matching file types.
- Users who keep
caspianSecurity.enabledLanguageslocked to code-only languages won't see IaC findings inside VS Code — the CLI still scans them in CI.
v9.5.0 — intra-file taint tracking, multi-line context fix, OAuth/LDAP/cmd/proto
[9.5.0] - 2026-04-21
Phase 3 of the roadmap. Caspian gains its first dataflow-aware analysis (intra-file taint tracking), a multi-line context fix that unblocks strict CI gating, and four new vulnerability-class families. The single biggest detection-quality jump since v8.0.
Added — taint tracking (the moat)
-
Intra-file taint engine (src/taint.ts) — Caspian's first dataflow-aware analysis. Tracks user-input sources (
req.body / query / params / headers, Flaskrequest.*, PHP$_GET / $_POST,process.argv / env, Pythonsys.argv / os.environ) through simple variable assignments forward to dangerous sinks within the same function. Findings are emitted as 8 new rule codes:TAINT001command injection (exec / spawn)TAINT002eval /new Function/vm.runInNewContextTAINT003filesystem path (path traversal)TAINT004SQL sinks (.query / .execute / .raw)TAINT005open redirect (res.redirect / sendRedirect)TAINT006reflected XSS (res.send / .innerHTML / document.write)TAINT007SSRF with provenance (fetch / axios / requestswith tainted URL)TAINT008prototype pollution viaObject.assign / _.merge / jQuery.extend
Sanitiser-aware: drops taint when the value passes through
validator.*,DOMPurify.sanitize,escape*,Number / parseInt, Zod / Joi.parse,new URL(...),path.resolve(...)+startsWith,express-validator. Performance-bounded: 200 lines / function, 50 in-flight tainted vars, 100 ms / file deadline. New settingcaspianSecurity.enableTaintTracking(defaulttrue) gates the pass. -
Limits documented openly in the rule messages: no cross-function, no cross-file, no aliasing through arrays / objects / destructuring. Catches the 60–70 % of vulns that happen in a single controller; the rest needs a real taint analyser (Semgrep / CodeQL).
Added — vulnerability coverage
- OAuth hygiene (
OAUTH001–OAUTH006) — callback handlescodewithoutstateverification (CSRF), authorize URL missingstate, code exchange without PKCE, open-redirect viaredirect_uri, deprecated implicit flow, wildcardscope. Slotted into AuthAccessControl. - LDAP injection (
LDAP001–LDAP003) — filter built via concatenation / template literal / Python f-string; JavaDirContext.searchwithoutLdapEncoder.filterEncode; Pythonpython-ldap.search_swithoutescape_filter_chars. Slotted into AuthAccessControl. - Command injection (
CMD001–CMD007) — Nodeexecwith concatenated input,spawn({shell:true}), Pythonos.system / subprocess(shell=True), PHPshell_exec / passthruwith$_GET / $_POST, Ruby string-formsystem / backticks / IO.popen, JavaRuntime.exec / ProcessBuilderwith concatenation. Slotted into APISecurity. - Prototype pollution expansion (
FE007a/FE007b/FE007c) —Object.assign({}, req.body), lodash_.merge / _.defaultsDeepwith untrusted source,{...req.body}spread without schema validation. OriginalFE007(__proto__literal) gainscontextAware: true.
Fixed — F11 multi-line context awareness
- New shared module src/scanContext.ts with
buildLineStates(text)— one-pass char-by-char walker that records per-line state (inside template literal, inside block comment, inside${}expression). Handles JS regex literals correctly, including character classes (/[...]/), so/\/g` no longer cascades the walker into a phantom template-literal state for the rest of the file. - Both
analyzer.ts(extension host) andcli/scan.tsconsume it.contextAwarerules now correctly skip matches inside multi-line template literals, JSDoc blocks, and across${...}expressions. Removes ~70 lines of duplicated context logic. XSS001/XSS002/CRED001markedcontextAware: trueso doc examples and webview-generation template literals stop false-positiving in projects that emit HTML to webviews.- Self-scan CI flipped back to
--fail-on error(was softened in v9.3.0). Caspian's own source now passes the strict gate.
Changed
- Rule totals: 240+ → 270+. Test suite: 812 → 880. Two new test suites (
scanContext.test.ts,taint.test.ts). .github/workflows/self-scan.ymlexcludes__tests__,rules,cli(rationale documented in the workflow file — each is its own intentional design).