canship 0.3.0 → 0.3.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 CHANGED
@@ -46,6 +46,7 @@ npx canship .
46
46
  | `--only=ids` | 仅执行匹配规则,支持逗号分隔及重复参数 |
47
47
  | `--skip=ids` | 排除匹配规则,支持逗号分隔及重复参数 |
48
48
  | `--no-config` | 忽略项目配置 |
49
+ | `--no-ignore-markers` | 不遵从被扫描源码中的忽略标记 |
49
50
  | `--list-rules` | 列出规则及限制,不扫描;支持 `--json` |
50
51
  | `--no-excerpts` | 所有报告省略源码摘录,不改变结果和退出码 |
51
52
  | `-h`, `--help` | 显示帮助 |
@@ -74,7 +75,7 @@ JSON 使用独立于包版本的 `schemaVersion: 1`,npm 包附带 [结构定
74
75
 
75
76
  保存为 `.github/workflows/canship.yml`,在推送和 PR 时扫描并生成统计摘要。安装扫描器需要联网,扫描不联网;不安装或执行项目依赖,默认不上传 SARIF。
76
77
 
77
- 示例固定 Action 提交,安装 npm 版 `0.2.1`;`version` 不使用仓库中的未发布源码。Action 兼容 0.2.1 无 `schemaVersion` 的报告。
78
+ 示例固定 Action 提交,显式安装 npm 版 `0.3.0`;`version` 不使用仓库中的未发布源码。Action 兼容 0.2.1 无 `schemaVersion` 的报告。
78
79
 
79
80
  ```yaml
80
81
  name: canship
@@ -89,15 +90,15 @@ jobs:
89
90
  with:
90
91
  fetch-depth: 0
91
92
  persist-credentials: false
92
- - uses: Tasomei/canship@37cf06e014168968a88679157564e5c489f99c50
93
+ - uses: Tasomei/canship@8b1a3aa88c77e92e2806b343af6003372855bc70
93
94
  with:
94
- version: '0.2.1'
95
+ version: '0.3.0'
95
96
  ```
96
97
 
97
98
  | 输入 | 默认值 | 说明 |
98
99
  |---|---|---|
99
100
  | `path` | `.` | 检出目录内的扫描路径 |
100
- | `version` | `0.2.1` | 精确 npm 版本,不接受范围或标签 |
101
+ | `version` | `0.3.0` | 精确 npm 版本,不接受范围或标签 |
101
102
  | `fail-on` | `blocking` | `blocking`:确定的 P0/P1;`any`:全部结果;`none`:仅报告结果 |
102
103
  | `only` / `skip` | 未设置 | 互斥,逗号分隔的规则选择器 |
103
104
  | `baseline` | 未设置 | 相对扫描目录的已有基线 |
@@ -120,7 +121,7 @@ jobs:
120
121
  }
121
122
  ```
122
123
 
123
- 命令行参数优先;`only`、`skip` 互斥,接受规则 ID 或命名空间。未选规则不执行,`ruleSelection.removed` 仅统计已执行规则中被过滤的结果。扫描不可信项目时使用 `--no-config`;`bestEffort` 仅限命令行设置。
124
+ 命令行参数优先;`only`、`skip` 互斥,接受规则 ID 或命名空间。未选规则不执行,`ruleSelection.removed` 仅统计已执行规则中被过滤的结果。扫描不可信项目时同时使用 `--no-config --no-ignore-markers`,二者均由被扫描项目控制;`bestEffort` 仅限命令行设置。
124
125
 
125
126
  ### 忽略标记
126
127
 
@@ -131,7 +132,7 @@ jobs:
131
132
  const corsOptions = { origin: '*', credentials: true }
132
133
  ```
133
134
 
134
- 报告披露忽略、规则筛选和基线抑制信息;主动排除不标记为未完成。
135
+ 报告披露忽略、规则筛选和基线抑制信息;主动排除不标记为未完成。标记可使退出码降为 `0`;`--no-config` 不影响标记,`--no-ignore-markers` 使两种标记均失效。
135
136
 
136
137
  ### 基线
137
138
 
package/README.md CHANGED
@@ -46,6 +46,7 @@ Omitting the path scans the current directory.
46
46
  | `--only=ids` | Run matching rules; comma-separated and repeatable |
47
47
  | `--skip=ids` | Exclude matching rules; comma-separated and repeatable |
48
48
  | `--no-config` | Ignore project configuration |
49
+ | `--no-ignore-markers` | Disregard ignore markers in scanned source |
49
50
  | `--list-rules` | List rules and limits without scanning; supports `--json` |
50
51
  | `--no-excerpts` | Omit source excerpts from every report; preserve findings and exit status |
51
52
  | `-h`, `--help` | Show help |
@@ -74,7 +75,7 @@ JSON uses `schemaVersion: 1`, independent of the package version; the npm packag
74
75
 
75
76
  Save as `.github/workflows/canship.yml` to scan on pushes and pull requests, with a counts-only summary. Scanner installation requires network access; scanning does not. Project dependencies are not installed or executed, and SARIF upload is disabled by default.
76
77
 
77
- The example pins the Action commit and installs npm version `0.2.1`; `version` does not use unreleased repository source. The Action accepts 0.2.1 reports without `schemaVersion`.
78
+ The example pins the Action commit and explicitly installs npm version `0.3.0`; `version` does not use unreleased repository source. The Action accepts 0.2.1 reports without `schemaVersion`.
78
79
 
79
80
  ```yaml
80
81
  name: canship
@@ -89,15 +90,15 @@ jobs:
89
90
  with:
90
91
  fetch-depth: 0
91
92
  persist-credentials: false
92
- - uses: Tasomei/canship@37cf06e014168968a88679157564e5c489f99c50
93
+ - uses: Tasomei/canship@8b1a3aa88c77e92e2806b343af6003372855bc70
93
94
  with:
94
- version: '0.2.1'
95
+ version: '0.3.0'
95
96
  ```
96
97
 
97
98
  | Input | Default | Meaning |
98
99
  |---|---|---|
99
100
  | `path` | `.` | Directory within the checkout |
100
- | `version` | `0.2.1` | Exact npm version; no ranges or tags |
101
+ | `version` | `0.3.0` | Exact npm version; no ranges or tags |
101
102
  | `fail-on` | `blocking` | `blocking`: certain P0/P1; `any`: all findings; `none`: findings only reported |
102
103
  | `only` / `skip` | unset | Mutually exclusive, comma-separated rule selectors |
103
104
  | `baseline` | unset | Existing baseline relative to the scanned directory |
@@ -120,7 +121,7 @@ Place `canship.config.json` in the scanned directory. Supported keys: `baseline`
120
121
  }
121
122
  ```
122
123
 
123
- CLI options take precedence. `only` and `skip` are mutually exclusive and accept rule IDs or namespaces. Unselected rules do not run; `ruleSelection.removed` counts filtered findings only from executed rules. Use `--no-config` for untrusted projects. `bestEffort` is CLI-only.
124
+ CLI options take precedence. `only` and `skip` are mutually exclusive and accept rule IDs or namespaces. Unselected rules do not run; `ruleSelection.removed` counts filtered findings only from executed rules. For untrusted projects use `--no-config --no-ignore-markers`; the scanned project controls both. `bestEffort` is CLI-only.
124
125
 
125
126
  ### Ignore markers
126
127
 
@@ -131,7 +132,7 @@ A standalone `canship-ignore-file` comment excludes a file; `canship-ignore-next
131
132
  const corsOptions = { origin: '*', credentials: true }
132
133
  ```
133
134
 
134
- Reports disclose exclusions, rule selection, and baseline suppression. Deliberate exclusions do not mark the scan incomplete.
135
+ Reports disclose exclusions, rule selection, and baseline suppression. Deliberate exclusions do not mark the scan incomplete. Markers can lower the exit code to `0`; `--no-config` does not affect them, `--no-ignore-markers` disables both kinds.
135
136
 
136
137
  ### Baselines
137
138
 
package/dist/cli.js CHANGED
@@ -779,7 +779,7 @@ function isExampleContext(relPath) {
779
779
  if (/\.(test|spec)\.[jt]sx?$/i.test(name)) return true;
780
780
  return false;
781
781
  }
782
- function collectFiles(root, isGitRepo, gitExecutable = resolveGitExecutable(root), limits = {}) {
782
+ function collectFiles(root, isGitRepo, gitExecutable = resolveGitExecutable(root), limits = {}, honorIgnoreMarkers = true) {
783
783
  const skipped = [];
784
784
  const ignored = [];
785
785
  const fromGit = isGitRepo ? listViaGit(root, gitExecutable) : null;
@@ -863,7 +863,7 @@ function collectFiles(root, isGitRepo, gitExecutable = resolveGitExecutable(root
863
863
  continue;
864
864
  }
865
865
  const lines = content.split(/\r?\n/);
866
- if (hasIgnoreMarker(lines)) {
866
+ if (honorIgnoreMarkers && hasIgnoreMarker(lines)) {
867
867
  ignored.push(relPath);
868
868
  continue;
869
869
  }
@@ -3453,7 +3453,8 @@ async function scan(root, options = {}) {
3453
3453
  const started = Date.now();
3454
3454
  const gitExecutable = resolveGitExecutable(root);
3455
3455
  const git2 = detectGitRepo(root, gitExecutable);
3456
- const { files, skipped, ignored, vendored } = collectFiles(root, git2 === "repo", gitExecutable);
3456
+ const honorIgnoreMarkers = options.honorIgnoreMarkers !== false;
3457
+ const { files, skipped, ignored, vendored } = collectFiles(root, git2 === "repo", gitExecutable, {}, honorIgnoreMarkers);
3457
3458
  const findings = [];
3458
3459
  const errors = [];
3459
3460
  const fileRules = FILE_RULES.filter((rule2) => shouldRunRule(rule2.id, options.only ?? [], options.skip ?? []));
@@ -3488,10 +3489,8 @@ async function scan(root, options = {}) {
3488
3489
  errors.push({ ruleId: rule2.id, file: null, message: messageOf(err), kind: "crashed" });
3489
3490
  }
3490
3491
  }
3491
- const { kept, ignored: ignoredFindings } = suppressIgnoredLines(
3492
- dedupe(downgradeExampleContext(findings, files)),
3493
- files
3494
- );
3492
+ const deduped = dedupe(downgradeExampleContext(findings, files));
3493
+ const { kept, ignored: ignoredFindings } = honorIgnoreMarkers ? suppressIgnoredLines(deduped, files) : { kept: deduped, ignored: [] };
3495
3494
  const selected = applyRuleSelection(kept, options);
3496
3495
  const counts = /* @__PURE__ */ new Map();
3497
3496
  const bounded = sortFindings(selected.kept).filter((finding) => {
@@ -4626,7 +4625,7 @@ function renderRuleCatalog() {
4626
4625
  }
4627
4626
 
4628
4627
  // src/cli.ts
4629
- var VERSION = true ? "0.3.0" : "0.0.0-dev";
4628
+ var VERSION = true ? "0.3.1" : "0.0.0-dev";
4630
4629
  function finish(code) {
4631
4630
  process.exitCode = code;
4632
4631
  }
@@ -4691,6 +4690,7 @@ function parseArgs(argv) {
4691
4690
  skip: [],
4692
4691
  sarif: null,
4693
4692
  noConfig: false,
4693
+ noIgnoreMarkers: false,
4694
4694
  help: false,
4695
4695
  version: false,
4696
4696
  listRules: false,
@@ -4759,6 +4759,9 @@ function parseArgs(argv) {
4759
4759
  case "--no-config":
4760
4760
  args.noConfig = true;
4761
4761
  break;
4762
+ case "--no-ignore-markers":
4763
+ args.noIgnoreMarkers = true;
4764
+ break;
4762
4765
  case "--list-rules":
4763
4766
  args.listRules = true;
4764
4767
  break;
@@ -4807,6 +4810,9 @@ var HELP = `
4807
4810
  --sarif[=F] Write a SARIF 2.1.0 log for CI code scanning
4808
4811
  (default canship.sarif)
4809
4812
  --no-config Ignore canship.config.json in the scanned directory
4813
+ --no-ignore-markers
4814
+ Disregard canship-ignore-file and canship-ignore-next-line
4815
+ markers; use with --no-config for untrusted projects
4810
4816
  --list-rules List rule IDs, scope, and limits; add --json for structured output
4811
4817
  --no-excerpts Omit source excerpts from every report; paths and descriptions remain
4812
4818
  -h, --help Show this help
@@ -4887,7 +4893,7 @@ async function main() {
4887
4893
  const showAll = args.showAll || config.all === true;
4888
4894
  const bestEffort = args.bestEffort;
4889
4895
  const baselinePath = args.baseline !== null ? resolve2(args.baseline) : args.baselineDefault ? resolve2(args.root, DEFAULT_BASELINE_PATH) : config.baseline !== void 0 ? insideProject(args.root, config.baseline) : null;
4890
- const scanned = await scan(args.root, { only, skip });
4896
+ const scanned = await scan(args.root, { only, skip, honorIgnoreMarkers: !args.noIgnoreMarkers });
4891
4897
  if (args.baselineWrite !== null || args.baselineWriteDefault) {
4892
4898
  const target = args.baselineWrite !== null ? resolve2(args.baselineWrite) : resolve2(args.root, DEFAULT_BASELINE_PATH);
4893
4899
  const baseline = buildBaseline(scanned.findings);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "canship",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Static scanner for exposed credentials and open access rules in JS/TS front-end projects. Scans local files without executing project code or making network requests.",
5
5
  "keywords": [
6
6
  "security",