npm-scan-plus 1.0.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.
Files changed (56) hide show
  1. package/.eslintrc.json +32 -0
  2. package/.github/CODEOWNERS +3 -0
  3. package/.github/workflows/ci.yml +105 -0
  4. package/.prettierrc +10 -0
  5. package/FUNDING.yml +1 -0
  6. package/PLAN.md +151 -0
  7. package/README.md +150 -0
  8. package/bin/npm-scan +13 -0
  9. package/bin/npm-scan-wrap +100 -0
  10. package/dist/cli/index.d.ts +18 -0
  11. package/dist/cli/index.d.ts.map +1 -0
  12. package/dist/cli/index.js +299 -0
  13. package/dist/cli/index.js.map +1 -0
  14. package/dist/lib/blocklist.d.ts +45 -0
  15. package/dist/lib/blocklist.d.ts.map +1 -0
  16. package/dist/lib/blocklist.js +256 -0
  17. package/dist/lib/blocklist.js.map +1 -0
  18. package/dist/lib/extended.js +314 -0
  19. package/dist/lib/extended.js.map +1 -0
  20. package/dist/lib/integrity.js +247 -0
  21. package/dist/lib/integrity.js.map +1 -0
  22. package/dist/lib/patterns.d.ts +76 -0
  23. package/dist/lib/patterns.d.ts.map +1 -0
  24. package/dist/lib/patterns.js +414 -0
  25. package/dist/lib/patterns.js.map +1 -0
  26. package/dist/lib/registry.d.ts +42 -0
  27. package/dist/lib/registry.d.ts.map +1 -0
  28. package/dist/lib/registry.js +157 -0
  29. package/dist/lib/registry.js.map +1 -0
  30. package/dist/lib/scanner.d.ts +43 -0
  31. package/dist/lib/scanner.d.ts.map +1 -0
  32. package/dist/lib/scanner.js +432 -0
  33. package/dist/lib/scanner.js.map +1 -0
  34. package/dist/lib/vuln.js +284 -0
  35. package/dist/lib/vuln.js.map +1 -0
  36. package/dist/types.d.ts +85 -0
  37. package/dist/types.d.ts.map +1 -0
  38. package/dist/types.js +6 -0
  39. package/dist/types.js.map +1 -0
  40. package/jest.config.js +18 -0
  41. package/package.json +56 -0
  42. package/src/cli/index.ts +336 -0
  43. package/src/lib/blocklist.ts +239 -0
  44. package/src/lib/extended.ts +384 -0
  45. package/src/lib/integrity.ts +253 -0
  46. package/src/lib/patterns.ts +404 -0
  47. package/src/lib/registry.ts +146 -0
  48. package/src/lib/scanner.ts +447 -0
  49. package/src/lib/vuln.ts +321 -0
  50. package/src/types.ts +102 -0
  51. package/tests/blocklist.test.ts +89 -0
  52. package/tests/extended.test.ts +204 -0
  53. package/tests/patterns.test.ts +147 -0
  54. package/tests/scanner.test.ts +116 -0
  55. package/tests/vuln.test.ts +66 -0
  56. package/tsconfig.json +20 -0
@@ -0,0 +1,284 @@
1
+ "use strict";
2
+ /**
3
+ * Vulnerability databases API integration
4
+ * OSV, GitHub Advisory, npm Audit
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.npmAuditClient = exports.githubAdvisoryClient = exports.osvClient = exports.VulnerabilityChecker = exports.NpmAuditClient = exports.GitHubAdvisoryClient = exports.OSVClient = void 0;
8
+ exports.createVulnerabilityChecker = createVulnerabilityChecker;
9
+ const OSV_API = 'https://api.osv.dev/v1/query';
10
+ const GITHUB_ADVISORIES_API = 'https://api.github.com/advisories';
11
+ const NPM_AUDIT_API = 'https://registry.npmjs.org/-/npm/v1/security/advisors';
12
+ /**
13
+ * OSV (Open Source Vulnerabilities) API client
14
+ * Free database maintained by Google
15
+ */
16
+ class OSVClient {
17
+ apiUrl = OSV_API;
18
+ /**
19
+ * Query OSV for vulnerabilities in a package
20
+ */
21
+ async checkPackage(packageName, version) {
22
+ const query = {
23
+ package: {
24
+ name: packageName,
25
+ ecosystem: 'npm'
26
+ }
27
+ };
28
+ if (version) {
29
+ query.version = version;
30
+ }
31
+ try {
32
+ const response = await fetch(this.apiUrl, {
33
+ method: 'POST',
34
+ headers: {
35
+ 'Content-Type': 'application/json'
36
+ },
37
+ body: JSON.stringify(query)
38
+ });
39
+ if (!response.ok) {
40
+ return [];
41
+ }
42
+ const data = await response.json();
43
+ const vulns = data.vulns || [];
44
+ return vulns.map(v => ({
45
+ id: v.id,
46
+ source: 'osv',
47
+ severity: this.mapSeverity(v.severity),
48
+ summary: v.summary,
49
+ details: v.details,
50
+ aliases: v.aliases,
51
+ patched_versions: this.getPatchedVersions(v.affected),
52
+ affected_versions: this.getAffectedVersions(v.affected),
53
+ references: v.references?.map((r) => r.url),
54
+ published: v.published,
55
+ modified: v.modified
56
+ }));
57
+ }
58
+ catch (error) {
59
+ console.error('OSV API error:', error);
60
+ return [];
61
+ }
62
+ }
63
+ /**
64
+ * Map OSV severity to our severity
65
+ */
66
+ mapSeverity(severity) {
67
+ const s = String(severity || '').toLowerCase();
68
+ if (s === 'critical')
69
+ return 'critical';
70
+ if (s === 'high')
71
+ return 'high';
72
+ if (s === 'medium')
73
+ return 'medium';
74
+ return 'low';
75
+ }
76
+ /**
77
+ * Extract patched versions from OSV affected field
78
+ */
79
+ getPatchedVersions(affected) {
80
+ if (!affected || affected.length === 0)
81
+ return undefined;
82
+ for (const a of affected) {
83
+ if (a.versions && a.ranges) {
84
+ for (const range of a.ranges) {
85
+ if (range.type === 'semver' && range.events) {
86
+ for (const event of range.events) {
87
+ if (event.introduced || event.fixed) {
88
+ return event.fixed || '<' + event.introduced;
89
+ }
90
+ }
91
+ }
92
+ }
93
+ }
94
+ }
95
+ return undefined;
96
+ }
97
+ /**
98
+ * Get affected versions string
99
+ */
100
+ getAffectedVersions(affected) {
101
+ if (!affected || affected.length === 0)
102
+ return undefined;
103
+ const versions = affected.map(a => a.package?.version).filter(Boolean);
104
+ return versions.length > 0 ? versions.join(', ') : undefined;
105
+ }
106
+ }
107
+ exports.OSVClient = OSVClient;
108
+ /**
109
+ * GitHub Advisory Database API client
110
+ * Requires authentication for higher rate limits
111
+ */
112
+ class GitHubAdvisoryClient {
113
+ token;
114
+ apiUrl = GITHUB_ADVISORIES_API;
115
+ constructor(token) {
116
+ this.token = token || process.env.GITHUB_TOKEN;
117
+ }
118
+ /**
119
+ * Fetch advisories for a specific package
120
+ */
121
+ async checkPackage(packageName) {
122
+ // GitHub advisories are fetched from the ecosystem-wide list
123
+ // We filter by package name client-side
124
+ try {
125
+ const response = await fetch(`${this.apiUrl}?ecosystem=npm&package=${packageName}`, {
126
+ headers: this.getHeaders()
127
+ });
128
+ if (!response.ok) {
129
+ if (response.status === 403) {
130
+ console.warn('GitHub API rate limited. Set GITHUB_TOKEN for higher limits.');
131
+ }
132
+ return [];
133
+ }
134
+ const data = await response.json();
135
+ const advisories = data.advisories || [];
136
+ return advisories.map((a) => ({
137
+ id: a.ghsa_id || a.cve_id,
138
+ source: 'github',
139
+ severity: this.mapSeverity(a.severity),
140
+ summary: a.summary,
141
+ details: a.description,
142
+ aliases: a.cve_id ? [a.cve_id] : [],
143
+ patched_versions: a.vulnerabilities?.[0]?.patched_versions,
144
+ affected_versions: a.vulnerabilities?.[0]?.vulnerable_version_range,
145
+ references: a.references?.map((r) => r.url),
146
+ published: a.published_at,
147
+ modified: a.updated_at
148
+ }));
149
+ }
150
+ catch (error) {
151
+ console.error('GitHub Advisory API error:', error);
152
+ return [];
153
+ }
154
+ }
155
+ /**
156
+ * Map GitHub severity to our severity
157
+ */
158
+ mapSeverity(severity) {
159
+ const s = String(severity || '').toLowerCase();
160
+ if (s === 'critical')
161
+ return 'critical';
162
+ if (s === 'high')
163
+ return 'high';
164
+ if (s === 'medium')
165
+ return 'medium';
166
+ return 'low';
167
+ }
168
+ /**
169
+ * Get HTTP headers
170
+ */
171
+ getHeaders() {
172
+ const headers = {
173
+ 'Accept': 'application/vnd.github+json',
174
+ 'X-GitHub-Api-Version': '2022-11-28'
175
+ };
176
+ if (this.token) {
177
+ headers['Authorization'] = `Bearer ${this.token}`;
178
+ }
179
+ return headers;
180
+ }
181
+ }
182
+ exports.GitHubAdvisoryClient = GitHubAdvisoryClient;
183
+ /**
184
+ * npm Audit API client
185
+ * Official npm security advisories
186
+ */
187
+ class NpmAuditClient {
188
+ apiUrl = NPM_AUDIT_API;
189
+ /**
190
+ * Fetch advisories from npm
191
+ */
192
+ async checkPackage(packageName) {
193
+ try {
194
+ const response = await fetch(`${this.apiUrl}?package=${packageName}`, {
195
+ headers: {
196
+ 'Accept': 'application/json'
197
+ }
198
+ });
199
+ if (!response.ok) {
200
+ return [];
201
+ }
202
+ const data = await response.json();
203
+ const advisories = data.data || [];
204
+ return advisories.map((a) => ({
205
+ id: a.id,
206
+ source: 'npm',
207
+ severity: this.mapSeverity(a.severity),
208
+ summary: a.title,
209
+ details: a.url,
210
+ patched_versions: a.patched_versions,
211
+ affected_versions: a.vulnerable_versions,
212
+ references: [a.url].filter(Boolean),
213
+ published: a.published,
214
+ modified: a.modified
215
+ }));
216
+ }
217
+ catch (error) {
218
+ console.error('npm Audit API error:', error);
219
+ return [];
220
+ }
221
+ }
222
+ /**
223
+ * Map npm severity to our severity
224
+ */
225
+ mapSeverity(severity) {
226
+ const s = String(severity || '').toLowerCase();
227
+ if (s === 'critical')
228
+ return 'critical';
229
+ if (s === 'high')
230
+ return 'high';
231
+ if (s === 'medium')
232
+ return 'medium';
233
+ return 'low';
234
+ }
235
+ }
236
+ exports.NpmAuditClient = NpmAuditClient;
237
+ /**
238
+ * Combined vulnerability checker
239
+ * Queries all three sources
240
+ */
241
+ class VulnerabilityChecker {
242
+ osv;
243
+ github;
244
+ npmAudit;
245
+ constructor(githubToken) {
246
+ this.osv = new OSVClient();
247
+ this.github = new GitHubAdvisoryClient(githubToken);
248
+ this.npmAudit = new NpmAuditClient();
249
+ }
250
+ /**
251
+ * Check a package against all vulnerability databases
252
+ */
253
+ async checkPackage(packageName, version) {
254
+ const [osvVulns, githubVulns, npmVulns] = await Promise.all([
255
+ this.osv.checkPackage(packageName, version).catch(() => []),
256
+ this.github.checkPackage(packageName).catch(() => []),
257
+ this.npmAudit.checkPackage(packageName).catch(() => [])
258
+ ]);
259
+ // Deduplicate by CVE ID
260
+ const seen = new Set();
261
+ const combined = [];
262
+ for (const v of [...osvVulns, ...githubVulns, ...npmVulns]) {
263
+ const id = v.id || v.aliases?.[0];
264
+ if (id && !seen.has(id)) {
265
+ seen.add(id);
266
+ combined.push(v);
267
+ }
268
+ }
269
+ return {
270
+ packageName,
271
+ vulnerabilities: combined,
272
+ checkedAt: new Date().toISOString()
273
+ };
274
+ }
275
+ }
276
+ exports.VulnerabilityChecker = VulnerabilityChecker;
277
+ // Export factory functions
278
+ function createVulnerabilityChecker(token) {
279
+ return new VulnerabilityChecker(token);
280
+ }
281
+ exports.osvClient = new OSVClient();
282
+ exports.githubAdvisoryClient = new GitHubAdvisoryClient();
283
+ exports.npmAuditClient = new NpmAuditClient();
284
+ //# sourceMappingURL=vuln.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vuln.js","sourceRoot":"","sources":["../../src/lib/vuln.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * npm-scan type definitions
3
+ */
4
+ export interface PackageMetadata {
5
+ name: string;
6
+ version: string;
7
+ description?: string;
8
+ publisher?: {
9
+ username: string;
10
+ email: string;
11
+ };
12
+ maintainers?: Array<{
13
+ username: string;
14
+ email: string;
15
+ }>;
16
+ repository?: {
17
+ type: string;
18
+ url: string;
19
+ };
20
+ homepage?: string;
21
+ license?: string;
22
+ dependencies?: Record<string, string>;
23
+ devDependencies?: Record<string, string>;
24
+ peerDependencies?: Record<string, string>;
25
+ scripts?: Record<string, string>;
26
+ latest?: string;
27
+ time?: {
28
+ created: string;
29
+ modified: string;
30
+ };
31
+ }
32
+ export interface ScanResult {
33
+ packageName: string;
34
+ version: string;
35
+ status: 'safe' | 'warning' | 'danger' | 'blocked';
36
+ threats: Threat[];
37
+ metadata?: PackageMetadata;
38
+ score: number;
39
+ }
40
+ export interface Threat {
41
+ type: ThreatType;
42
+ severity: 'low' | 'medium' | 'high' | 'critical';
43
+ message: string;
44
+ details?: string;
45
+ location?: string;
46
+ }
47
+ export type ThreatType = 'blocklisted' | 'vulnerability' | 'obfuscation' | 'suspicious_code' | 'typosquatting' | 'supply_chain' | 'suspicious_script' | 'unknown_publisher' | 'dependency_confusion';
48
+ export interface BlocklistEntry {
49
+ package: string;
50
+ reason: string;
51
+ addedAt: string;
52
+ severity: 'high' | 'critical';
53
+ source?: string;
54
+ }
55
+ export interface ScanOptions {
56
+ registry?: string;
57
+ blocklist?: string[];
58
+ checkVulnerabilities?: boolean;
59
+ checkObfuscation?: boolean;
60
+ checkPatterns?: boolean;
61
+ timeout?: number;
62
+ }
63
+ export interface PostInstallScanResult {
64
+ scannedPackages: number;
65
+ threats: FileThreat[];
66
+ duration: number;
67
+ }
68
+ export interface FileThreat {
69
+ package: string;
70
+ file: string;
71
+ type: ThreatType;
72
+ severity: 'low' | 'medium' | 'high' | 'critical';
73
+ message: string;
74
+ line?: number;
75
+ code?: string;
76
+ }
77
+ export interface CliOptions {
78
+ command: 'pre' | 'post' | 'scan' | 'blocklist';
79
+ subcommand?: 'add' | 'remove' | 'list';
80
+ package?: string;
81
+ version?: string;
82
+ folder?: string;
83
+ verbose?: boolean;
84
+ }
85
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ /**
3
+ * npm-scan type definitions
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA;;GAEG"}
package/jest.config.js ADDED
@@ -0,0 +1,18 @@
1
+ module.exports = {
2
+ preset: 'ts-jest',
3
+ testEnvironment: 'node',
4
+ roots: ['<rootDir>/tests'],
5
+ testMatch: ['**/*.test.ts'],
6
+ collectCoverageFrom: [
7
+ 'src/lib/**/*.ts',
8
+ '!src/**/*.d.ts'
9
+ ],
10
+ coverageDirectory: 'coverage',
11
+ coverageReporters: ['text', 'lcov', 'html'],
12
+ moduleFileExtensions: ['ts', 'js', 'json'],
13
+ transform: {
14
+ '^.+\\.ts$': 'ts-jest'
15
+ },
16
+ verbose: true,
17
+ testTimeout: 30000
18
+ };
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "npm-scan-plus",
3
+ "version": "1.0.0",
4
+ "description": "Security scanner for npm packages - pre and post-install scanning for malicious code, supply chain attacks, and obfuscated code",
5
+ "main": "dist/lib/index.js",
6
+ "types": "dist/lib/index.d.ts",
7
+ "bin": {
8
+ "npm-scan": "./bin/npm-scan.js",
9
+ "npm-scan-wrap": "./bin/npm-scan-wrap"
10
+ },
11
+ "scripts": {
12
+ "build": "tsc",
13
+ "test": "jest",
14
+ "lint": "eslint src tests --ext .ts",
15
+ "lint:fix": "eslint src tests --ext .ts --fix",
16
+ "format": "prettier --write src tests",
17
+ "prepare": "npm run build"
18
+ },
19
+ "keywords": [
20
+ "security",
21
+ "npm",
22
+ "scanner",
23
+ "malware",
24
+ "supply-chain",
25
+ "obfuscation",
26
+ "vulnerabilities",
27
+ "infosec"
28
+ ],
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "https://github.com/cbuntingde/npm-scan.git"
32
+ },
33
+ "author": "Chris Bunting <cbuntingde@github.com>",
34
+ "license": "MIT",
35
+ "dependencies": {
36
+ "tar": "^6.2.1",
37
+ "semver": "^7.6.0"
38
+ },
39
+ "devDependencies": {
40
+ "@types/node": "^20.11.0",
41
+ "@types/tar": "^6.1.11",
42
+ "@types/semver": "^7.5.6",
43
+ "@typescript-eslint/eslint-plugin": "^6.21.0",
44
+ "@typescript-eslint/parser": "^6.21.0",
45
+ "eslint": "^8.56.0",
46
+ "prettier": "^3.2.5",
47
+ "typescript": "^5.3.3",
48
+ "jest": "^29.7.0",
49
+ "@types/jest": "^29.5.12",
50
+ "ts-jest": "^29.1.2",
51
+ "ts-node": "^10.9.2"
52
+ },
53
+ "engines": {
54
+ "node": ">=18.0.0"
55
+ }
56
+ }