canship 0.7.0 → 0.8.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README-zh-CN.md +61 -124
- package/README.md +62 -125
- package/dist/cli.js +4050 -816
- package/dist/index.d.ts +78 -8
- package/dist/index.js +1450 -305
- package/docs/framework-support-zh-CN.md +95 -0
- package/docs/framework-support.md +95 -0
- package/docs/reference-zh-CN.md +221 -0
- package/docs/reference.md +221 -0
- package/package.json +13 -2
- package/schemas/config-v1.schema.json +114 -0
- package/schemas/scan-report-v1.schema.json +19 -1
package/README-zh-CN.md
CHANGED
|
@@ -1,20 +1,30 @@
|
|
|
1
1
|
# canship
|
|
2
2
|
|
|
3
|
-
面向 JavaScript / TypeScript Web
|
|
3
|
+
面向 JavaScript / TypeScript Web 应用的本地静态扫描器,检测凭据暴露、访问控制配置错误及请求输入风险。
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
静态扫描离线、只读,不执行项目代码。部署校验为独立功能,须显式确认请求计划。
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
[English](./README.md) · [使用参考](./docs/reference-zh-CN.md) · [npm](https://www.npmjs.com/package/canship)
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
> 候选版本 `0.8.0-rc.1` 使用 npm `next` 渠道。下方示例固定此预发布版本;稳定版 `0.7.1` 请参阅[发行版文档](https://github.com/Tasomei/canship/blob/v0.7.1/README-zh-CN.md)。
|
|
10
|
+
|
|
11
|
+
## 扫描项目
|
|
12
|
+
|
|
13
|
+
要求 Node.js ≥18,无运行时依赖;安装可能联网。
|
|
14
|
+
|
|
15
|
+
```powershell
|
|
16
|
+
npx canship@0.8.0-rc.1
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
扫描其他目录:
|
|
10
20
|
|
|
11
21
|
```powershell
|
|
12
|
-
npx canship
|
|
22
|
+
npx canship@0.8.0-rc.1 "./my-app"
|
|
13
23
|
```
|
|
14
24
|
|
|
15
|
-
|
|
25
|
+
Git 检查读取本地跟踪文件及提交历史,不访问远程仓库;历史无法读取时标记覆盖不完整。
|
|
16
26
|
|
|
17
|
-
|
|
27
|
+
以下截图使用开发构建及合成数据。
|
|
18
28
|
|
|
19
29
|

|
|
20
30
|
|
|
@@ -22,89 +32,53 @@ npx canship
|
|
|
22
32
|
|
|
23
33
|
| 类别 | 级别 | 范围 |
|
|
24
34
|
|---|:---:|---|
|
|
25
|
-
| 凭据 | `P0` |
|
|
35
|
+
| 凭据 | `P0` | 硬编码凭据、公开环境变量暴露、Supabase 管理员密钥、Git 跟踪或历史中的非模板 `.env` 文件 |
|
|
26
36
|
| API 访问 | `P0/P1` | 未识别到鉴权的数据库操作、服务端信任 Supabase `getSession()`、未验证的 Stripe webhook |
|
|
27
|
-
| 数据库规则 | `P1/P2` | Supabase
|
|
37
|
+
| 数据库规则 | `P1/P2` | Supabase RLS、无条件放行策略及公开对象列表;Firebase 开放规则及测试模式到期时间 |
|
|
28
38
|
| CORS | `P1/P2` | 携带凭据的来源回显或通配符配置 |
|
|
29
|
-
| 请求输入 | `P1/P2` |
|
|
39
|
+
| 请求输入 | `P1/P2` | SQL 和命令构造、调用方可控的请求主机及重定向目标 |
|
|
30
40
|
|
|
31
|
-
|
|
41
|
+
路由分析覆盖 Next.js、SvelteKit、Nuxt、Remix / React Router、Astro、Express、Hono、Fastify 的指定入口,不支持任意框架行为。详见[入口及限制](./docs/reference-zh-CN.md#服务端入口)。
|
|
32
42
|
|
|
33
|
-
|
|
43
|
+
```powershell
|
|
44
|
+
npx canship@0.8.0-rc.1 --list-rules
|
|
45
|
+
```
|
|
34
46
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
| SvelteKit | `+server` 端点、`+page.server` 表单 action |
|
|
39
|
-
| Nuxt | `server/api`、`server/routes` |
|
|
40
|
-
| Remix / React Router | `app/routes` 中的 `loader`、`action` 导出 |
|
|
41
|
-
| Astro | `src/pages` 中的端点 |
|
|
42
|
-
| Express | `app`/`Router` 路由,含 `.route()` 链、挂载的子路由和其他文件中的控制器 |
|
|
43
|
-
| Hono | `app.get()` 等路由、链式调用、`basePath`,以及 `app.route()` 挂载的子应用 |
|
|
44
|
-
| Fastify | 简写与 `route()` 声明、`register()` 前缀与封装作用域、`@fastify/autoload` 目录 |
|
|
47
|
+
## 审阅结果
|
|
48
|
+
|
|
49
|
+
报告正文为英文。`certain` 表示静态证据充分,`likely` 需人工审阅。测试和示例中的结果降为 `likely`;置信度不代表凭据有效或风险可被利用。
|
|
45
50
|
|
|
46
|
-
|
|
51
|
+
显示全部置信度及详细证据:
|
|
47
52
|
|
|
48
|
-
|
|
53
|
+
```powershell
|
|
54
|
+
npx canship@0.8.0-rc.1 --all --verbose
|
|
55
|
+
```
|
|
49
56
|
|
|
50
|
-
|
|
57
|
+
生成离线 HTML 报告:
|
|
51
58
|
|
|
52
|
-
|
|
59
|
+
```powershell
|
|
60
|
+
npx canship@0.8.0-rc.1 --all --report
|
|
61
|
+
```
|
|
53
62
|
|
|
54
63
|

|
|
55
64
|
|
|
56
|
-
|
|
65
|
+
[合成 HTML 示例](https://github.com/Tasomei/canship/blob/main/docs/demo.html):下载文件后在本地打开,无需安装扫描器。
|
|
66
|
+
|
|
67
|
+
HTML 支持严重度及置信度筛选、稳定定位和修复提示复制。`--no-excerpts` 移除摘录,但保留路径等项目文本。`--share-summary` 仅输出计数及范围标记,分享前仍须审阅。
|
|
57
68
|
|
|
58
|
-
| 退出码 |
|
|
69
|
+
| 退出码 | 静态扫描结果 |
|
|
59
70
|
|---|---|
|
|
60
71
|
| `0` | 无结果,且扫描完整或由 `--best-effort` 接受 |
|
|
61
72
|
| `1` | 至少一条 `certain` 的 P0/P1 结果 |
|
|
62
73
|
| `2` | 其他结果,包括隐藏的 `likely` |
|
|
63
74
|
| `3` | 参数错误、工具错误或未被接受的不完整扫描 |
|
|
75
|
+
| `130` / `143` | 收到 SIGINT / SIGTERM,不生成扫描报告 |
|
|
64
76
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
## 命令行
|
|
68
|
-
|
|
69
|
-
`npx canship [path] [options]`
|
|
70
|
-
|
|
71
|
-
| 参数 | 作用 |
|
|
72
|
-
|---|---|
|
|
73
|
-
| `-a`、`--all` | 包含 `likely` 结果 |
|
|
74
|
-
| `--verbose` | 展开终端结果 |
|
|
75
|
-
| `--report[=file]` | 写入 HTML,默认 `canship-report.html` |
|
|
76
|
-
| `--open` | 打开 `--report` 输出;CI 和非交互终端中禁用 |
|
|
77
|
-
| `--json` | 输出 JSON |
|
|
78
|
-
| `--sarif[=file]` | 写入 SARIF 2.1.0,默认 `canship.sarif` |
|
|
79
|
-
| `--fix-prompt` | 输出修复指令及独立的人工操作清单 |
|
|
80
|
-
| `--no-excerpts` | 移除所有报告中的摘录 |
|
|
81
|
-
| `--changed-since=ref` | 展示变更文件结果,保留全量扫描退出码 |
|
|
82
|
-
| `--only=ids` / `--skip=ids` | 选择或排除规则及命名空间,逗号分隔,可重复 |
|
|
83
|
-
| `--list-rules` | 列出规则而不扫描,支持 `--json` |
|
|
84
|
-
| `--baseline[=file]` / `--baseline-write[=file]` | 抑制或记录结果,默认 `canship-baseline.json` |
|
|
85
|
-
| `--no-config` / `--no-ignore-markers` | 忽略项目配置或源码抑制注释 |
|
|
86
|
-
| `--best-effort` | 允许没有结果的不完整扫描退出 `0` |
|
|
87
|
-
| `-h`、`--help` / `-v`、`--version` | 显示帮助或版本 |
|
|
88
|
-
|
|
89
|
-
`--json` 与 `--fix-prompt` 互斥,均可同时输出 HTML 和 SARIF。
|
|
90
|
-
|
|
91
|
-
`--changed-since` 比较本地共同祖先与工作区,包含未被忽略的新文件,不拉取远程、不缩小扫描范围。缺少 Git、引用或共同历史时退出 `3`;不能与 `--baseline-write` 组合。
|
|
92
|
-
|
|
93
|
-
## 配置
|
|
94
|
-
|
|
95
|
-
`canship.config.json` 支持 `baseline`、`only`、`skip`、`all`。命令行参数优先,`only` 与 `skip` 互斥。
|
|
96
|
-
|
|
97
|
-
```json
|
|
98
|
-
{ "skip": ["cors/wildcard-with-credentials"], "all": false }
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
独占行注释 `canship-ignore-file` 排除整个文件;`canship-ignore-next-line [rule]` 抑制下一行,可限定单条规则。报告披露排除项;主动抑制不标记扫描不完整,可能使退出码降为 `0`。扫描不可信项目时使用 `--no-config --no-ignore-markers`。
|
|
102
|
-
|
|
103
|
-
基线表示接受已有结果,不代表问题已修复。v2 格式不受行号移动影响,但凭据变化会重新报告。
|
|
77
|
+
退出码基于规则选择、源码抑制及基线处理后的结果。有结果时优先于覆盖不完整;`--best-effort` 不改变 `1` 或 `2`。须另行检查 JSON 的 `partial`、`errors`、`skipped` 和 `filesScanned`。
|
|
104
78
|
|
|
105
|
-
|
|
79
|
+
基线表示接受结果,不代表问题已修复。[基线管理](./docs/reference-zh-CN.md#配置)支持审阅已有记录、选择性接受、理由及到期时间。[报告比较](./docs/reference-zh-CN.md#命令行)提供终端、JSON 和离线 HTML 视图,区分新增、持续存在及本次未再出现,不将结果消失视为修复证明。
|
|
106
80
|
|
|
107
|
-
##
|
|
81
|
+
## 接入 CI
|
|
108
82
|
|
|
109
83
|
保存为 `.github/workflows/canship.yml`:
|
|
110
84
|
|
|
@@ -121,78 +95,41 @@ jobs:
|
|
|
121
95
|
with:
|
|
122
96
|
fetch-depth: 0
|
|
123
97
|
persist-credentials: false
|
|
124
|
-
- uses: Tasomei/canship@
|
|
98
|
+
- uses: Tasomei/canship@7465c9560b8b3692777af080e8cc67b4be2335d7
|
|
125
99
|
with:
|
|
126
|
-
version: '0.
|
|
100
|
+
version: '0.8.0-rc.1'
|
|
127
101
|
honor-ignore-markers: false
|
|
128
102
|
```
|
|
129
103
|
|
|
130
|
-
提交哈希固定 Action
|
|
104
|
+
提交哈希固定 Action 实现;`version` 指定此 npm 候选版本,须在候选包公开后启用工作流。Action 使用 Node.js 22,不安装或运行项目依赖,仅输出统计摘要。
|
|
131
105
|
|
|
132
|
-
| 输入 |
|
|
106
|
+
| 输入 | 固定 Action 的默认值 | 含义 |
|
|
133
107
|
|---|---|---|
|
|
134
|
-
| `version` | `0.
|
|
108
|
+
| `version` | `0.7.0` | 精确 npm 版本;上例已覆盖 |
|
|
135
109
|
| `fail-on` | `blocking` | `blocking`:确定的 P0/P1;`any`:全部结果;`none`:仅报告 |
|
|
136
110
|
|
|
137
|
-
扫描不完整或工具错误始终失败。默认不读取项目配置、不上传 SARIF
|
|
138
|
-
|
|
139
|
-
上传 SARIF 需 `security-events: write` 及代码扫描支持,fork PR 可能权限不足;上传前应审阅报告。不可信 PR 使用 `pull_request`,不要使用 `pull_request_target`。
|
|
111
|
+
扫描不完整或工具错误始终失败。默认不读取项目配置、不上传 SARIF。上传需 `security-events: write` 及代码扫描支持,操作前须审阅报告。不可信 PR 使用 `pull_request`,不要使用 `pull_request_target`。详见 [Action 输入](https://github.com/Tasomei/canship/blob/main/action.yml)。
|
|
140
112
|
|
|
141
|
-
##
|
|
113
|
+
## 进阶用法
|
|
142
114
|
|
|
143
|
-
|
|
144
|
-
import { scan, summarize } from 'canship'
|
|
145
|
-
|
|
146
|
-
const result = await scan('./my-app', { noExcerpts: true })
|
|
147
|
-
console.log(summarize(result))
|
|
148
|
-
```
|
|
115
|
+
[完整命令参考](./docs/reference-zh-CN.md#命令行)涵盖 JSON/SARIF、规则选择、配置、排除项、独立工作区、诊断及模板预览。[API](./docs/reference-zh-CN.md#api-与结构化输出)返回结构化结果,不加载项目配置、不写文件。
|
|
149
116
|
|
|
150
|
-
|
|
117
|
+
pre-commit 模板扫描**工作区,而非暂存区快照**。部署校验默认关闭,仅支持无认证的 HTTPS 请求;使用前须审阅[范围与隐私限制](./docs/reference-zh-CN.md#部署校验)。
|
|
151
118
|
|
|
152
|
-
|
|
119
|
+
[VS Code 插件](https://github.com/Tasomei/canship/tree/main/extensions/vscode#readme)为独立开发预览,本地 VSIX 打包及已验证宿主范围见插件 README;尚未发布到 Marketplace。
|
|
153
120
|
|
|
154
121
|
## 隐私与限制
|
|
155
122
|
|
|
156
|
-
-
|
|
157
|
-
-
|
|
158
|
-
- Google/Firebase/Maps 的 `AIza…` 密钥按公开标识符处理,不单凭其值判定泄露。
|
|
159
|
-
-
|
|
160
|
-
-
|
|
161
|
-
|
|
162
|
-
| 项目 | 上限 |
|
|
163
|
-
|---|---|
|
|
164
|
-
| 文件读取 | 单文件 2 MiB;单次 128 MiB、10,000 个文件,含探测 |
|
|
165
|
-
| 目录遍历 | 50,000 个条目;16 层 |
|
|
166
|
-
| 结果 | 每文件 100 条,优先保留高严重度、高置信度结果 |
|
|
167
|
-
| Git 历史 | 每文件 100 个相关版本;单条命令 30 秒 |
|
|
168
|
-
| 鉴权辅助函数解析 | 8 跳;每个辅助函数 64 个符号,每个路由文件共 1,024 个 |
|
|
169
|
-
| 委托写入 | 调用 2 层;每个文件 256 个被调函数;超出部分的写入不报告 |
|
|
170
|
-
| 身份/控制流 | 值解析 8 步;表达式 4,000 字符;每函数 512 个赋值/区域;区域嵌套 8 层 |
|
|
171
|
-
| 请求输入追踪 | 值解析 8 步;512 个赋值/区域;单条表达式 64 KiB;URL 分析 8 层、静态前缀 200 字符 |
|
|
172
|
-
| Supabase 策略/存储桶解析 | 单条语句 4,000 字符 |
|
|
173
|
-
|
|
174
|
-
证据链最多 24 步,截断时提示。
|
|
175
|
-
|
|
176
|
-
## 开发
|
|
177
|
-
|
|
178
|
-
```powershell
|
|
179
|
-
npm ci
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
```powershell
|
|
183
|
-
npm run prepublishOnly
|
|
184
|
-
```
|
|
123
|
+
- 静态分析可能误报或漏报,不验证业务授权、限流或依赖漏洞。
|
|
124
|
+
- 脱敏仅覆盖已识别格式,未知敏感值可能保留在摘录中;详细报告及基线应按内部材料处理。
|
|
125
|
+
- Google/Firebase/Maps 的 `AIza…` 密钥按公开标识符处理,不单凭其值判定泄露。
|
|
126
|
+
- 不跟随符号链接;嵌套仓库及子模块须单独扫描。范围内跳过项及分析上限会披露;默认排除的依赖和构建目录不计为覆盖缺口。
|
|
127
|
+
- 显式部署校验会访问已确认目标;安装、评估下载及可选 SARIF 上传也可能联网。静态扫描保持离线。
|
|
185
128
|
|
|
186
|
-
|
|
187
|
-
npm run test:package
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
```powershell
|
|
191
|
-
npm run evaluate
|
|
192
|
-
```
|
|
129
|
+
详见[资源上限与覆盖边界](./docs/reference-zh-CN.md#隐私与限制)。
|
|
193
130
|
|
|
194
|
-
|
|
131
|
+
## 开发与许可
|
|
195
132
|
|
|
196
|
-
|
|
133
|
+
分别运行 `npm ci`、`npm run prepublishOnly`、`npm run test:package`、`npm run evaluate`。新增规则须包含应检出和不应检出的夹具;样本通过不代表真实检出率。详见[开发参考](./docs/reference-zh-CN.md#开发)。
|
|
197
134
|
|
|
198
135
|
[MIT](./LICENSE)。Supabase/Firebase 夹具保留 Apache-2.0,Next.js/`cors` 夹具保留 MIT。
|
package/README.md
CHANGED
|
@@ -1,20 +1,30 @@
|
|
|
1
1
|
# canship
|
|
2
2
|
|
|
3
|
-
A local static scanner for JavaScript and TypeScript web apps.
|
|
3
|
+
A local static scanner for JavaScript and TypeScript web apps. Detects exposed credentials, access-control misconfiguration, and unsafe request-input flows.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Static scans are offline, read-only, and execute no project code. Deployment probes are separate and require explicit plan confirmation.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
[简体中文](./README-zh-CN.md) · [Reference](./docs/reference.md) · [npm](https://www.npmjs.com/package/canship)
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
> Release candidate `0.8.0-rc.1` for npm `next`. Examples below pin this prerelease. For stable `0.7.1`, see the [release documentation](https://github.com/Tasomei/canship/blob/v0.7.1/README.md).
|
|
10
|
+
|
|
11
|
+
## Scan a project
|
|
12
|
+
|
|
13
|
+
Requires Node.js ≥18. No runtime dependencies; installation may use the network.
|
|
14
|
+
|
|
15
|
+
```powershell
|
|
16
|
+
npx canship@0.8.0-rc.1
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
To scan another directory:
|
|
10
20
|
|
|
11
21
|
```powershell
|
|
12
|
-
npx canship
|
|
22
|
+
npx canship@0.8.0-rc.1 "./my-app"
|
|
13
23
|
```
|
|
14
24
|
|
|
15
|
-
|
|
25
|
+
Git checks inspect locally tracked files and commit history without contacting remotes. Unreadable history marks coverage incomplete.
|
|
16
26
|
|
|
17
|
-
|
|
27
|
+
The following screenshots use synthetic data from a development build.
|
|
18
28
|
|
|
19
29
|

|
|
20
30
|
|
|
@@ -22,89 +32,53 @@ Output examples use sample data from a pre-release development build.
|
|
|
22
32
|
|
|
23
33
|
| Category | Severity | Scope |
|
|
24
34
|
|---|:---:|---|
|
|
25
|
-
| Credentials | `P0` | Hardcoded
|
|
35
|
+
| Credentials | `P0` | Hardcoded credentials, public env exposure, Supabase admin keys, non-template `.env` files tracked by Git or present in history |
|
|
26
36
|
| API access | `P0/P1` | Database operations without recognised authentication, server-side trust in Supabase `getSession()`, unverified Stripe webhooks |
|
|
27
|
-
| Database rules | `P1/P2` | Supabase
|
|
37
|
+
| Database rules | `P1/P2` | Supabase RLS, unconditional policies and public object listing; Firebase open rules and test-mode expiry |
|
|
28
38
|
| CORS | `P1/P2` | Reflected or wildcard origins with credentials |
|
|
29
|
-
| Request input | `P1/P2` |
|
|
39
|
+
| Request input | `P1/P2` | SQL and command construction, caller-controlled request hosts and redirect targets |
|
|
30
40
|
|
|
31
|
-
|
|
41
|
+
Route analysis supports documented entry points in Next.js, SvelteKit, Nuxt, Remix / React Router, Astro, Express, Hono and Fastify—not arbitrary framework behaviour. See [entry points and limits](./docs/reference.md#server-entry-points).
|
|
32
42
|
|
|
33
|
-
|
|
43
|
+
```powershell
|
|
44
|
+
npx canship@0.8.0-rc.1 --list-rules
|
|
45
|
+
```
|
|
34
46
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
| SvelteKit | `+server` endpoints and `+page.server` form actions |
|
|
39
|
-
| Nuxt | `server/api`, `server/routes` |
|
|
40
|
-
| Remix / React Router | `loader` and `action` exports in `app/routes` |
|
|
41
|
-
| Astro | Endpoints in `src/pages` |
|
|
42
|
-
| Express | `app`/`Router` routes, including `.route()` chains, mounted routers, and controllers in other files |
|
|
43
|
-
| Hono | `app.get()`-style routes, chains, `basePath`, and sub-apps mounted with `app.route()` |
|
|
44
|
-
| Fastify | Shorthand and `route()` declarations, `register()` prefixes and encapsulation, `@fastify/autoload` directories |
|
|
47
|
+
## Review results
|
|
48
|
+
|
|
49
|
+
Reports are in English. `certain` means strong static evidence; `likely` requires review. Tests and examples are downgraded to `likely`. Neither confidence level proves credential validity or exploitability.
|
|
45
50
|
|
|
46
|
-
|
|
51
|
+
Show all confidence levels and detailed evidence:
|
|
47
52
|
|
|
48
|
-
|
|
53
|
+
```powershell
|
|
54
|
+
npx canship@0.8.0-rc.1 --all --verbose
|
|
55
|
+
```
|
|
49
56
|
|
|
50
|
-
|
|
57
|
+
Generate an offline HTML report:
|
|
51
58
|
|
|
52
|
-
|
|
59
|
+
```powershell
|
|
60
|
+
npx canship@0.8.0-rc.1 --all --report
|
|
61
|
+
```
|
|
53
62
|
|
|
54
63
|

|
|
55
64
|
|
|
56
|
-
|
|
65
|
+
[Synthetic HTML sample](https://github.com/Tasomei/canship/blob/main/docs/demo.html): download the file and open it locally; no scanner installation is required.
|
|
66
|
+
|
|
67
|
+
HTML provides severity/confidence filters, stable finding links, and copyable repair prompts. Use `--no-excerpts` to omit excerpts; paths and other project text remain. For counts without project text, use `--share-summary` and review before sharing.
|
|
57
68
|
|
|
58
|
-
| Exit |
|
|
69
|
+
| Exit | Static scan result |
|
|
59
70
|
|---|---|
|
|
60
71
|
| `0` | No findings; coverage complete or accepted with `--best-effort` |
|
|
61
72
|
| `1` | At least one `certain` P0/P1 finding |
|
|
62
73
|
| `2` | Other findings, including hidden `likely` results |
|
|
63
74
|
| `3` | Invalid arguments, tool error, or unaccepted incomplete coverage |
|
|
75
|
+
| `130` / `143` | Interrupted by SIGINT / SIGTERM; no scan report generated |
|
|
64
76
|
|
|
65
|
-
Status is calculated after rule selection,
|
|
66
|
-
|
|
67
|
-
## CLI
|
|
68
|
-
|
|
69
|
-
`npx canship [path] [options]`
|
|
70
|
-
|
|
71
|
-
| Option | Effect |
|
|
72
|
-
|---|---|
|
|
73
|
-
| `-a`, `--all` | Include `likely` findings |
|
|
74
|
-
| `--verbose` | Expand terminal findings |
|
|
75
|
-
| `--report[=file]` | Write HTML; default `canship-report.html` |
|
|
76
|
-
| `--open` | Open `--report` output; disabled in CI and non-interactive shells |
|
|
77
|
-
| `--json` | Print JSON |
|
|
78
|
-
| `--sarif[=file]` | Write SARIF 2.1.0; default `canship.sarif` |
|
|
79
|
-
| `--fix-prompt` | Print repair instructions and separate manual actions |
|
|
80
|
-
| `--no-excerpts` | Remove excerpts from all reports |
|
|
81
|
-
| `--changed-since=ref` | Show changed-file findings; preserve full-scan status |
|
|
82
|
-
| `--only=ids` / `--skip=ids` | Select/exclude rules or namespaces; comma-separated, repeatable |
|
|
83
|
-
| `--list-rules` | List rules without scanning; supports `--json` |
|
|
84
|
-
| `--baseline[=file]` / `--baseline-write[=file]` | Suppress/record findings; default `canship-baseline.json` |
|
|
85
|
-
| `--no-config` / `--no-ignore-markers` | Ignore project configuration/source suppression comments |
|
|
86
|
-
| `--best-effort` | Allow incomplete coverage with no findings to exit `0` |
|
|
87
|
-
| `-h`, `--help` / `-v`, `--version` | Show help/version |
|
|
88
|
-
|
|
89
|
-
`--json` and `--fix-prompt` are mutually exclusive; either supports HTML and SARIF output.
|
|
90
|
-
|
|
91
|
-
`--changed-since` compares the local merge base with the working tree, including non-ignored untracked files. It does not fetch or narrow scan scope. Missing Git, refs, or shared history exits `3`; it cannot be combined with `--baseline-write`.
|
|
92
|
-
|
|
93
|
-
## Configuration
|
|
94
|
-
|
|
95
|
-
`canship.config.json` accepts `baseline`, `only`, `skip`, and `all`. CLI options take precedence; `only` and `skip` are mutually exclusive.
|
|
96
|
-
|
|
97
|
-
```json
|
|
98
|
-
{ "skip": ["cors/wildcard-with-credentials"], "all": false }
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
A standalone `canship-ignore-file` comment excludes a file. `canship-ignore-next-line [rule]` suppresses the next line, optionally for one rule. Exclusions are disclosed and may reduce status to `0` without marking coverage incomplete. For untrusted projects, use `--no-config --no-ignore-markers`.
|
|
102
|
-
|
|
103
|
-
Baselines accept existing findings without fixing them. Format v2 tolerates line moves but reports credential changes.
|
|
77
|
+
Status is calculated after rule selection, source suppressions and baselines. Findings take precedence over incomplete coverage; `--best-effort` never changes `1` or `2`. Check JSON `partial`, `errors`, `skipped` and `filesScanned` separately.
|
|
104
78
|
|
|
105
|
-
|
|
79
|
+
Baselines accept findings; they do not fix them. Review existing decisions, accept selected results, and set optional reasons or expiry through [baseline management](./docs/reference.md#configuration). [Saved-report comparison](./docs/reference.md#cli) provides terminal, JSON and offline HTML views of added, persisting and no-longer-observed records without claiming remediation.
|
|
106
80
|
|
|
107
|
-
##
|
|
81
|
+
## Connect to CI
|
|
108
82
|
|
|
109
83
|
Save as `.github/workflows/canship.yml`:
|
|
110
84
|
|
|
@@ -121,78 +95,41 @@ jobs:
|
|
|
121
95
|
with:
|
|
122
96
|
fetch-depth: 0
|
|
123
97
|
persist-credentials: false
|
|
124
|
-
- uses: Tasomei/canship@
|
|
98
|
+
- uses: Tasomei/canship@7465c9560b8b3692777af080e8cc67b4be2335d7
|
|
125
99
|
with:
|
|
126
|
-
version: '0.
|
|
100
|
+
version: '0.8.0-rc.1'
|
|
127
101
|
honor-ignore-markers: false
|
|
128
102
|
```
|
|
129
103
|
|
|
130
|
-
The
|
|
104
|
+
The hash pins the Action implementation; `version` selects this npm release candidate. Enable the workflow after the candidate is public. The Action uses Node.js 22, does not install or run project dependencies, and writes a counts-only summary.
|
|
131
105
|
|
|
132
|
-
| Input |
|
|
106
|
+
| Input | Pinned Action default | Meaning |
|
|
133
107
|
|---|---|---|
|
|
134
|
-
| `version` | `0.
|
|
108
|
+
| `version` | `0.7.0` | Exact npm scanner version; overridden above |
|
|
135
109
|
| `fail-on` | `blocking` | `blocking`: certain P0/P1; `any`: all findings; `none`: report only |
|
|
136
110
|
|
|
137
|
-
Incomplete scans and tool errors always fail. Project configuration and SARIF upload are disabled by default.
|
|
138
|
-
|
|
139
|
-
SARIF upload requires `security-events: write` and code scanning support; fork PRs may lack permission. Review reports before upload. Use `pull_request`, not `pull_request_target`, for untrusted PRs.
|
|
140
|
-
|
|
141
|
-
## API and structured output
|
|
142
|
-
|
|
143
|
-
```js
|
|
144
|
-
import { scan, summarize } from 'canship'
|
|
145
|
-
|
|
146
|
-
const result = await scan('./my-app', { noExcerpts: true })
|
|
147
|
-
console.log(summarize(result))
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
`scan()` returns all confidence levels. Options: `only`, `skip`, `honorIgnoreMarkers` (default `true`), `noExcerpts` (default `false`). It does not load configuration, apply baselines, write reports, or set process exit status. Invalid arguments throw. `listRules()` returns the rule catalogue.
|
|
151
|
-
|
|
152
|
-
JSON uses [schemaVersion 1](./schemas/scan-report-v1.schema.json). Check `partial`, `errors`, `skipped`, and `filesScanned` independently of exit status. SARIF includes evidence locations and execution diagnostics.
|
|
153
|
-
|
|
154
|
-
## Privacy and limits
|
|
111
|
+
Incomplete scans and tool errors always fail. Project configuration and SARIF upload are disabled by default. Upload requires `security-events: write` and code scanning support; review reports first. Use `pull_request`, not `pull_request_target`, for untrusted PRs. See [Action inputs](https://github.com/Tasomei/canship/blob/main/action.yml).
|
|
155
112
|
|
|
156
|
-
|
|
157
|
-
- Redaction covers recognised formats only. Unknown secrets may remain in excerpts; `--no-excerpts` omits excerpts. Paths, names, and baseline descriptions remain visible.
|
|
158
|
-
- Google/Firebase/Maps `AIza…` keys are treated as public identifiers, not leak evidence alone. Supabase checks use local migrations and supported bucket configuration.
|
|
159
|
-
- Evaluation snapshot downloads and optional SARIF uploads may use the network.
|
|
160
|
-
- Symbolic links are not followed; nested repositories and submodules need separate scans. In-scope skipped paths and analysis limits mark coverage incomplete; auth helper resolution limits are noted on the affected finding instead, because they cannot hide findings. Dependency and build directories excluded by default do not count as coverage gaps.
|
|
113
|
+
## Advanced use
|
|
161
114
|
|
|
162
|
-
|
|
163
|
-
|---|---|
|
|
164
|
-
| File reads | 2 MiB per file; 128 MiB and 10,000 files per scan, including probes |
|
|
165
|
-
| Directory discovery | 50,000 entries; 16 levels |
|
|
166
|
-
| Findings | 100 per file, prioritising severity and confidence |
|
|
167
|
-
| Git history | 100 relevant revisions per file; 30 seconds per command |
|
|
168
|
-
| Auth helper resolution | 8 hops; 64 symbols per helper, 1,024 per route file |
|
|
169
|
-
| Delegated writes | 2 call levels; 256 callees per file; writes beyond these limits are not reported |
|
|
170
|
-
| Identity/control flow | 8 value hops; 4,000 expression characters; 512 assignments/regions per function; 8 nested regions |
|
|
171
|
-
| Request-input tracking | 8 value hops; 512 assignments/regions; 64 KiB per expression; 8 URL-analysis levels; 200 static-prefix characters |
|
|
172
|
-
| Supabase policy/bucket parsing | 4,000 characters per statement |
|
|
115
|
+
[Full CLI reference](./docs/reference.md#cli) covers JSON/SARIF output, rules, configuration, exclusions, independent workspaces, diagnostics and template previews. The [API](./docs/reference.md#api-and-structured-output) returns structured findings without loading project configuration or writing files.
|
|
173
116
|
|
|
174
|
-
|
|
117
|
+
The pre-commit template scans the **working tree, not the staged snapshot**. Deployment probes are opt-in, HTTPS-only and unauthenticated; [review their scope and privacy limits](./docs/reference.md#deployment-probes) before use.
|
|
175
118
|
|
|
176
|
-
|
|
119
|
+
The [VS Code extension](https://github.com/Tasomei/canship/tree/main/extensions/vscode#readme) is a separate development preview. See its README for local VSIX packaging and verified host coverage. Marketplace publication is pending.
|
|
177
120
|
|
|
178
|
-
|
|
179
|
-
npm ci
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
```powershell
|
|
183
|
-
npm run prepublishOnly
|
|
184
|
-
```
|
|
121
|
+
## Privacy and limitations
|
|
185
122
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
123
|
+
- Static analysis may miss issues or flag intentional configurations. It does not verify business authorisation, rate limiting or dependency vulnerabilities.
|
|
124
|
+
- Redaction covers recognised formats only. Unknown sensitive values may remain in excerpts; detailed reports and baselines should be treated as internal material.
|
|
125
|
+
- Google/Firebase/Maps `AIza…` keys are public identifiers, not leak evidence alone.
|
|
126
|
+
- Symbolic links are not followed. Nested repositories and submodules need separate scans. In-scope skips and analysis limits are disclosed; default dependency/build exclusions are not coverage gaps.
|
|
127
|
+
- Explicit deployment probes contact the approved target; installation, evaluation downloads and optional SARIF upload may also use the network. Static scans remain offline.
|
|
189
128
|
|
|
190
|
-
|
|
191
|
-
npm run evaluate
|
|
192
|
-
```
|
|
129
|
+
See [resource bounds and coverage limits](./docs/reference.md#privacy-and-limits).
|
|
193
130
|
|
|
194
|
-
|
|
131
|
+
## Development and license
|
|
195
132
|
|
|
196
|
-
|
|
133
|
+
Run `npm ci`, `npm run prepublishOnly`, `npm run test:package` and `npm run evaluate` separately. New rules require positive and negative fixtures; passing samples do not establish real-world detection rates. See [development reference](./docs/reference.md#development).
|
|
197
134
|
|
|
198
135
|
[MIT](./LICENSE). Supabase/Firebase fixtures retain Apache-2.0; Next.js/`cors` fixtures retain MIT.
|