sfscanner 0.0.0-stage → 0.2.0
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/LICENSE +21 -0
- package/README.md +131 -3
- package/THIRD_PARTY_NOTICES.md +48 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +10766 -0
- package/dist/index.js.map +7 -0
- package/dist/main.js +11941 -0
- package/dist/main.js.map +7 -0
- package/dist/mcp.js +10468 -0
- package/dist/mcp.js.map +7 -0
- package/dist/scan-worker.js +11800 -0
- package/dist/scan-worker.js.map +7 -0
- package/dist/v2/arguments.d.ts +87 -0
- package/dist/v2/arguments.js +403 -0
- package/dist/v2/arguments.js.map +7 -0
- package/dist/v2/atomic-output.d.ts +34 -0
- package/dist/v2/batch-runner.d.ts +50 -0
- package/dist/v2/cli-runner-internal.d.ts +28 -0
- package/dist/v2/cli-runner.d.ts +22 -0
- package/dist/v2/cli-runner.js +10037 -0
- package/dist/v2/cli-runner.js.map +7 -0
- package/dist/v2/commands.d.ts +155 -0
- package/dist/v2/config.d.ts +16 -0
- package/dist/v2/contracts.d.ts +97 -0
- package/dist/v2/exit-reducer.d.ts +23 -0
- package/dist/v2/help.d.ts +33 -0
- package/dist/v2/help.js +325 -0
- package/dist/v2/help.js.map +7 -0
- package/dist/v2/input-read.d.ts +26 -0
- package/dist/v2/input-selection.d.ts +38 -0
- package/dist/v2/json-output.d.ts +97 -0
- package/dist/v2/metadata-output.d.ts +37 -0
- package/dist/v2/metadata-output.js +7523 -0
- package/dist/v2/metadata-output.js.map +7 -0
- package/dist/v2/metadata-validation.d.ts +4 -0
- package/dist/v2/ndjson-output.d.ts +3 -0
- package/dist/v2/path-admission.d.ts +8 -0
- package/dist/v2/scan-config-load.d.ts +21 -0
- package/dist/v2/scan-worker-host.d.ts +29 -0
- package/dist/v2/table-output.d.ts +2 -0
- package/dist/v2/worker-host.d.ts +24 -0
- package/package.json +74 -6
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 n8n-secureflow contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,131 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
# sfscanner 🔍
|
|
2
|
+
|
|
3
|
+
**Deterministic, offline security scanning for n8n workflows** — JSON, NDJSON, a table, or SARIF 2.1.0. The workflow never leaves your machine.
|
|
4
|
+
|
|
5
|
+
> **Licensing:** MIT for this package's code and scanner tooling. The catalogue dataset has separate Personal / Non-Commercial terms; see https://github.com/jitwark/n8n-Secureflow/blob/main/docs/LICENSING.md.
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx sfscanner scan my-workflow.json
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
> This package is the scanner. The workflow **catalogue** — 11,464 public n8n workflows, their
|
|
12
|
+
> provenance and how much of each one the scanner could actually read — lives on the website:
|
|
13
|
+
> <https://n8n-enterprise-1.web.app>.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## ⚡ Quickstart
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# one file, human-readable
|
|
21
|
+
npx sfscanner --schema v2 scan workflow.json --format table
|
|
22
|
+
|
|
23
|
+
# a directory, SARIF for GitHub code scanning
|
|
24
|
+
npx sfscanner --schema v2 scan ./workflows --format sarif > results.sarif
|
|
25
|
+
|
|
26
|
+
# pipe a workflow straight from a clipboard or curl
|
|
27
|
+
cat workflow.json | npx sfscanner scan -
|
|
28
|
+
|
|
29
|
+
# see the rules, then read one in full
|
|
30
|
+
npx sfscanner --schema v2 rules --format table
|
|
31
|
+
npx sfscanner --schema v2 explain N8N_EXECUTE_COMMAND
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Node **22** is the only supported line (`engines: >=22 <23`). The CLI is ESM-only and no CommonJS artifact is shipped; `require('sfscanner')` is not supported. Runs have been verified on Windows; Linux and macOS are not yet a verified matrix.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## 🧠 What it actually checks
|
|
39
|
+
|
|
40
|
+
Seven admitted rules in the `beta-default` profile. Every row carries a severity, a confidence and a
|
|
41
|
+
CWE: these are deterministic pattern and configuration matches, **not** a safety guarantee, and not a
|
|
42
|
+
verdict about whether a workflow is safe to run.
|
|
43
|
+
|
|
44
|
+
| Rule | Severity | Confidence | CWE |
|
|
45
|
+
| --- | --- | --- | --- |
|
|
46
|
+
| `N8N_EXECUTE_COMMAND` | CRITICAL | HIGH | CWE-78 |
|
|
47
|
+
| `N8N_CODE_NODE` | LOW | HIGH | CWE-94 |
|
|
48
|
+
| `RAW_AUTH_HEADER` | HIGH | MEDIUM | CWE-522, CWE-798 |
|
|
49
|
+
| `RAW_SECRET_INDICATOR` | HIGH | MEDIUM | CWE-798 |
|
|
50
|
+
| `UNAPPROVED_DOMAIN` | MEDIUM | HIGH | — |
|
|
51
|
+
| `UNKNOWN_NODE_PACKAGE` | LOW | MEDIUM | CWE-1357 |
|
|
52
|
+
| `WEBHOOK_EXPOSURE` | MEDIUM | MEDIUM | CWE-306 |
|
|
53
|
+
|
|
54
|
+
The `beta-hardened` profile is **defined but not admitted** — `sfscanner --schema v2 profiles` says
|
|
55
|
+
so, and selecting it fails instead of silently running something weaker.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## 📤 Output and exit codes
|
|
60
|
+
|
|
61
|
+
Formats: `json` (default), `ndjson`, `sarif`, `table`. SARIF is 2.1.0 with CWE tags, so GitHub,
|
|
62
|
+
GitLab and VS Code can read it directly.
|
|
63
|
+
|
|
64
|
+
| Exit | Meaning |
|
|
65
|
+
| :---: | --- |
|
|
66
|
+
| `0` | Clean — nothing met the `--fail-on` threshold. |
|
|
67
|
+
| `1` | Findings at or above `--fail-on`, or a degraded result under `--require-complete`. |
|
|
68
|
+
| `2` | Usage or configuration error. |
|
|
69
|
+
| `3` | Malformed input, a failed/timed-out input, or an `INDETERMINATE` result — unless a finding at/above `--fail-on` already decided exit 1. |
|
|
70
|
+
| `4` | Internal error or a memory ceiling. |
|
|
71
|
+
| `130` | Interrupted. |
|
|
72
|
+
|
|
73
|
+
`--fail-on <CRITICAL|HIGH|MEDIUM|LOW|INFO>` (Default: `INFO`). `--schema v2` is required for
|
|
74
|
+
directory scans, `--output` and `--fail-on`; without it those are usage errors by design.
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## 🤖 MCP server
|
|
79
|
+
|
|
80
|
+
The package ships `sfscanner-mcp` — a stdio JSON-RPC MCP server with **one** tool, `n8n_scan`. It
|
|
81
|
+
scans local workflow files with the same engine and returns the same structured output, so an agent
|
|
82
|
+
can read a workflow before it imports it.
|
|
83
|
+
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"mcpServers": {
|
|
87
|
+
"sfscanner": {
|
|
88
|
+
"command": "node",
|
|
89
|
+
"args": ["<npm-root>/sfscanner/dist/mcp.js"]
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
`<npm-root>` is `npm root -g`. The single tool takes `inputs` (local paths; stdin `-` is refused
|
|
96
|
+
because the transport owns stdin), plus optional `format`, `failOn`, `profile`, `include`, `exclude`.
|
|
97
|
+
Invalid arguments answer JSON-RPC `-32602` without running a scan.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## 🛡️ Limits, honestly
|
|
102
|
+
|
|
103
|
+
- Inputs are bounded: 1,536,000 bytes per file by default, 5,000 nodes, 10,000 edges, a 30 s worker
|
|
104
|
+
deadline, and a validated `--limits` document can tighten or raise the byte ceiling.
|
|
105
|
+
- The scan runs in a worker; if the worker cannot be terminated the item is reported `FAILED` rather
|
|
106
|
+
than "probably fine".
|
|
107
|
+
- Node types the scanner does not model are reported as **unknown**, not as safe. Version ranges are
|
|
108
|
+
matched as catalogued; there is no nearest-neighbour guess.
|
|
109
|
+
- Coverage of the published corpus lives on the website, with explicit counts for bodies that are
|
|
110
|
+
missing, source-unavailable, degraded and indeterminate.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## 📚 Documentation
|
|
115
|
+
|
|
116
|
+
- [`docs/scanner/cli-v2.md`](../../docs/scanner/cli-v2.md) — v2 admission rules and Windows example
|
|
117
|
+
- [`docs/scanner/limitations.md`](../../docs/scanner/limitations.md) — what the scanner does not do
|
|
118
|
+
- [`docs/scanner/rule-reference.md`](../../docs/scanner/rule-reference.md) — every rule and remediation
|
|
119
|
+
- [`docs/scanner/migration-v1-v2.md`](../../docs/scanner/migration-v1-v2.md) — v1 remains supported
|
|
120
|
+
- [`docs/LICENSING.md`](../../docs/LICENSING.md) — licence terms
|
|
121
|
+
|
|
122
|
+
v1 (`sfscanner scan file.json`) still works for one input with the `beta-default` profile.
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## ⚖️ Licence
|
|
127
|
+
|
|
128
|
+
MIT for this package's code and scanner tooling. The catalogue dataset has separate Personal /
|
|
129
|
+
Non-Commercial terms; see https://github.com/jitwark/n8n-Secureflow/blob/main/docs/LICENSING.md.
|
|
130
|
+
The dataset is not shipped in this package. A finding tells you what to read before importing a
|
|
131
|
+
workflow; it does not make one safe.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Third-party notices
|
|
2
|
+
|
|
3
|
+
This package ships a built CLI bundle plus its own documentation. The package's own code is licensed
|
|
4
|
+
under [`LICENSE`](LICENSE) (MIT). No workflow corpus, private repository data, or runtime network
|
|
5
|
+
client is included in this package.
|
|
6
|
+
|
|
7
|
+
The classification below is derived from the packed artifact, not from declared intent: a module
|
|
8
|
+
counts as shipped only when the bundle's shipped `dist/*.js.map` sources name it. The same split is
|
|
9
|
+
machine-readable in `outputs/distribution/scanner-sbom.cyclonedx.json`
|
|
10
|
+
(`scope` plus the `sfscanner:observed-in-packed-artifact` property).
|
|
11
|
+
|
|
12
|
+
## Inlined in the packed bundle
|
|
13
|
+
|
|
14
|
+
| Component | Version | License |
|
|
15
|
+
| --- | --- | --- |
|
|
16
|
+
| `@humanwhocodes/momoa` | 3.3.10 | Apache-2.0 |
|
|
17
|
+
| `@noble/hashes` | 2.3.0 | MIT |
|
|
18
|
+
| `@hub/contracts` | 0.1.0 | MIT — this project's workspace package |
|
|
19
|
+
| `@hub/scanner-core` | 0.1.0 | MIT — this project's workspace package |
|
|
20
|
+
|
|
21
|
+
`@hub/contracts` and `@hub/scanner-core` are this project's own MIT-licensed workspace packages. Their
|
|
22
|
+
code is compiled into `dist/main.js` and `dist/mcp.js`; they are not runtime package dependencies.
|
|
23
|
+
|
|
24
|
+
## Declared runtime dependencies this build does not ship
|
|
25
|
+
|
|
26
|
+
These packages are installed as runtime dependencies of `@hub/scanner-core` and are imported by its
|
|
27
|
+
optional code-analysis modules, but they are unreachable from this CLI's admitted profile
|
|
28
|
+
(`beta-default` only, `packages/scanner-cli/src/v2/commands.ts`), so they are tree-shaken out of the
|
|
29
|
+
packed bundle. They are listed because their absence is a verified property of this artifact: the
|
|
30
|
+
string `acorn` / `@lezer` occurs zero times anywhere under `packages/scanner-cli/dist`, and the
|
|
31
|
+
shipped source maps name none of their modules.
|
|
32
|
+
|
|
33
|
+
| Component | Version | License |
|
|
34
|
+
| --- | --- | --- |
|
|
35
|
+
| `acorn` | 8.17.0 | MIT |
|
|
36
|
+
| `@lezer/common` | 1.5.2 | MIT |
|
|
37
|
+
| `@lezer/highlight` | 1.2.3 | MIT |
|
|
38
|
+
| `@lezer/lr` | 1.4.10 | MIT |
|
|
39
|
+
| `@lezer/python` | 1.1.19 | MIT |
|
|
40
|
+
|
|
41
|
+
The scanner package's build/test-only tooling (`esbuild`, `typescript`, `vitest`, `@types/node` and
|
|
42
|
+
their transitive dependencies) is likewise absent from the packed artifact and carries no notice
|
|
43
|
+
obligation for it.
|
|
44
|
+
|
|
45
|
+
This is a prepared dependency inventory, not a claim that the release's notice obligations are
|
|
46
|
+
complete. A release owner must reconcile these versions against the exact lockfile, attach the
|
|
47
|
+
verbatim upstream license texts, and complete the legal review (`PENDING_OWNER`). This package is
|
|
48
|
+
published on npm as `sfscanner`.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { parseCliArguments } from './v2/arguments.js';
|
|
2
|
+
export { runCliV2, type PublicRunOptionsV2, type PublicRunResultV2, type PublicScanCommandV2, } from './v2/cli-runner.js';
|
|
3
|
+
export { getHelpV2 } from './v2/help.js';
|
|
4
|
+
export { emitMetadataCommandResultV2 } from './v2/metadata-output.js';
|