dsh-plugin-inspector 0.2.1 → 0.4.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/README.md +48 -392
- package/lib/checks/tier-a.js +18 -7
- package/lib/checks/tier-b.js +38 -6
- package/lib/checks/tier-c.js +25 -0
- package/lib/cli.js +5 -0
- package/lib/cordis-yaml.js +78 -42
- package/lib/files.js +2 -0
- package/lib/injection.js +16 -0
- package/lib/inspect.js +15 -2
- package/lib/knowledge.js +38 -0
- package/lib/manifest.js +1 -0
- package/lib/publish.js +2 -0
- package/lib/registry.js +1 -0
- package/lib/report.js +5 -0
- package/lib/source.js +11 -8
- package/lib/types/checks/tier-b.d.ts +20 -0
- package/lib/types/cordis-yaml.d.ts +15 -2
- package/lib/types/inspect.d.ts +12 -2
- package/lib/types/knowledge.d.ts +24 -0
- package/lib/types/source.d.ts +9 -7
- package/package.json +1 -1
|
@@ -14,6 +14,26 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import type { Finding } from '../model.ts';
|
|
16
16
|
import type { CheckInput } from './input.ts';
|
|
17
|
+
/** One filesystem location that holds credentials, and how it is spelled. */
|
|
18
|
+
export interface CredentialPath {
|
|
19
|
+
readonly id: string;
|
|
20
|
+
/** Pattern source, matched case-insensitively anywhere in a string literal. */
|
|
21
|
+
readonly pattern: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Filesystem locations that hold credentials.
|
|
25
|
+
*
|
|
26
|
+
* A table rather than one regular expression so each location can be pinned by
|
|
27
|
+
* name: `tests/unit/rule-tables.spec.ts` iterates this export, and a location
|
|
28
|
+
* added without a fixture fails there.
|
|
29
|
+
*/
|
|
30
|
+
export declare const CREDENTIAL_PATHS: readonly CredentialPath[];
|
|
31
|
+
/**
|
|
32
|
+
* Whether a string names a location that holds credentials.
|
|
33
|
+
* @param text - the literal text of a string in shipped source.
|
|
34
|
+
* @returns true when it names one of {@link CREDENTIAL_PATHS}.
|
|
35
|
+
*/
|
|
36
|
+
export declare function matchesCredentialPath(text: string): boolean;
|
|
17
37
|
/**
|
|
18
38
|
* Run every Tier B check.
|
|
19
39
|
* @param input - the decoded package.
|
|
@@ -82,10 +82,23 @@ export interface PatchDocument {
|
|
|
82
82
|
* means the layer was read in part, which Tier C reports.
|
|
83
83
|
*/
|
|
84
84
|
readonly limit: WalkLimit;
|
|
85
|
+
/**
|
|
86
|
+
* True when the layer reached at least one node twice, which is what a YAML
|
|
87
|
+
* alias does and what nothing else does. Tier C reports it, because a reader
|
|
88
|
+
* of the file sees one row where the loader sees two.
|
|
89
|
+
*/
|
|
90
|
+
readonly aliased: boolean;
|
|
85
91
|
}
|
|
86
|
-
/**
|
|
92
|
+
/**
|
|
93
|
+
* The two ceilings that make reading a patch layer terminate.
|
|
94
|
+
*
|
|
95
|
+
* They apply to {@link expandAliases}, and through it to everything downstream:
|
|
96
|
+
* the walk runs over the tree the expansion produced, which holds at most
|
|
97
|
+
* `MAX_WALK_NODES` nodes nested at most `MAX_WALK_DEPTH` deep, so the walk needs
|
|
98
|
+
* no ceiling of its own.
|
|
99
|
+
*/
|
|
87
100
|
export declare const MAX_WALK_NODES = 200000;
|
|
88
|
-
/** Nesting one patch layer may reach before the
|
|
101
|
+
/** Nesting one patch layer may reach before the reader gives up. */
|
|
89
102
|
export declare const MAX_WALK_DEPTH = 200;
|
|
90
103
|
/** Thrown when the patch file cannot be parsed as an entry list. */
|
|
91
104
|
export declare class PatchParseError extends Error {
|
package/lib/types/inspect.d.ts
CHANGED
|
@@ -11,8 +11,18 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import { type RegistryProvenance, type Report, type Severity } from './model.ts';
|
|
13
13
|
import { type PluginSource } from './source.ts';
|
|
14
|
-
/**
|
|
15
|
-
|
|
14
|
+
/**
|
|
15
|
+
* This tool's own version, reported in the JSON document, by `--version`, and
|
|
16
|
+
* in the recorded ecosystem measurement.
|
|
17
|
+
*
|
|
18
|
+
* Read from this package's own `package.json` rather than written down a second
|
|
19
|
+
* time. A constant is a copy that only a release checklist keeps honest, and it
|
|
20
|
+
* stopped being honest for two releases: every report claimed `0.1.0` while the
|
|
21
|
+
* published package was `0.2.1`. The manifest sits one directory above this
|
|
22
|
+
* module in the source tree, in `lib/` after a build, and in the published
|
|
23
|
+
* tarball, so the same relative path resolves in all three.
|
|
24
|
+
*/
|
|
25
|
+
export declare const TOOL_VERSION: string;
|
|
16
26
|
/** This tool's package name, reported in the JSON document. */
|
|
17
27
|
export declare const TOOL_NAME = "dsh-plugin-inspector";
|
|
18
28
|
/**
|
package/lib/types/knowledge.d.ts
CHANGED
|
@@ -110,6 +110,30 @@ export declare const SKILL_ROOT_CONFIG_KEYS: readonly string[];
|
|
|
110
110
|
* only needs one of these to run code before the user has read a line of it.
|
|
111
111
|
*/
|
|
112
112
|
export declare const INSTALL_LIFECYCLE_SCRIPTS: readonly string[];
|
|
113
|
+
/** One thing a lifecycle command can do that a build never needs to. */
|
|
114
|
+
export interface LifecycleSignal {
|
|
115
|
+
readonly id: string;
|
|
116
|
+
readonly pattern: RegExp;
|
|
117
|
+
/** What the match means, phrased for a report. */
|
|
118
|
+
readonly meaning: string;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Command shapes that make an install lifecycle script the attack rather than
|
|
122
|
+
* the build.
|
|
123
|
+
*
|
|
124
|
+
* The case this table is for is the one where the command line itself fetches,
|
|
125
|
+
* decodes, or evaluates: the whole attack sits in `package.json` and there is
|
|
126
|
+
* no shipped module to read. A lifecycle hook alone does not distinguish that
|
|
127
|
+
* from a build, which is why the hook is a category at `medium` and only the
|
|
128
|
+
* command raises it.
|
|
129
|
+
*
|
|
130
|
+
* Each pattern is chosen against the measured false-positive side rather than
|
|
131
|
+
* against the idea of a build script. The five packages in the pinned corpus
|
|
132
|
+
* that declare a hook run `tsdown`, `npm run build`, `husky`, and
|
|
133
|
+
* `node scripts/prepare.mjs`; running a shipped file is what a build hook is, so
|
|
134
|
+
* that shape is deliberately not a signal here.
|
|
135
|
+
*/
|
|
136
|
+
export declare const LIFECYCLE_SIGNALS: readonly LifecycleSignal[];
|
|
113
137
|
/** Entry fields the loader never interpolates: a `!!js` node here is inert data. */
|
|
114
138
|
export declare const STATIC_ENTRY_FIELDS: readonly string[];
|
|
115
139
|
/**
|
package/lib/types/source.d.ts
CHANGED
|
@@ -26,11 +26,20 @@ export declare const MAX_FILE_BYTES: number;
|
|
|
26
26
|
export declare const MAX_TOTAL_BYTES: number;
|
|
27
27
|
/** Largest number of files the analyzer will consider. */
|
|
28
28
|
export declare const MAX_ENTRIES = 10000;
|
|
29
|
+
/**
|
|
30
|
+
* Decompressed tar bytes one tarball may produce before the read is abandoned.
|
|
31
|
+
*
|
|
32
|
+
* Eight times the in-memory ceiling. A plugin tarball is never this large, and
|
|
33
|
+
* one that is has already answered the only question worth asking about it.
|
|
34
|
+
*/
|
|
35
|
+
export declare const MAX_STREAM_BYTES: number;
|
|
29
36
|
/** The resource ceilings one read runs under. */
|
|
30
37
|
export interface ReadLimits {
|
|
31
38
|
readonly maxFileBytes: number;
|
|
32
39
|
readonly maxTotalBytes: number;
|
|
33
40
|
readonly maxEntries: number;
|
|
41
|
+
/** Decompressed tar bytes one tarball may produce before the read is abandoned. */
|
|
42
|
+
readonly maxStreamBytes: number;
|
|
34
43
|
}
|
|
35
44
|
/** The shipping ceilings. Tests substitute smaller ones to exercise each cap. */
|
|
36
45
|
export declare const DEFAULT_LIMITS: ReadLimits;
|
|
@@ -58,13 +67,6 @@ export interface PluginSource {
|
|
|
58
67
|
/** Working-tree files npm would not publish, and which were therefore not read. */
|
|
59
68
|
readonly unpublishedFiles: number;
|
|
60
69
|
}
|
|
61
|
-
/**
|
|
62
|
-
* Decompressed tar bytes one tarball may produce before the read is abandoned.
|
|
63
|
-
*
|
|
64
|
-
* Eight times the in-memory ceiling. A plugin tarball is never this large, and
|
|
65
|
-
* one that is has already answered the only question worth asking about it.
|
|
66
|
-
*/
|
|
67
|
-
export declare const MAX_STREAM_BYTES: number;
|
|
68
70
|
/**
|
|
69
71
|
* Read the package under analysis.
|
|
70
72
|
* @param target - a plugin directory, or a `.tgz` / `.tar.gz` npm tarball.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-plugin-inspector",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Know what a DeepSeek Harness plugin does before you install it — static pre-install analysis of a plugin directory or tarball",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Ivan Tyshchenko",
|