guardrail-security 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 (95) hide show
  1. package/dist/attack-surface/analyzer.d.ts +50 -0
  2. package/dist/attack-surface/analyzer.d.ts.map +1 -0
  3. package/dist/attack-surface/analyzer.js +83 -0
  4. package/dist/attack-surface/index.d.ts +5 -0
  5. package/dist/attack-surface/index.d.ts.map +1 -0
  6. package/dist/attack-surface/index.js +20 -0
  7. package/dist/index.d.ts +15 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +33 -0
  10. package/dist/languages/index.d.ts +21 -0
  11. package/dist/languages/index.d.ts.map +1 -0
  12. package/dist/languages/index.js +78 -0
  13. package/dist/languages/java-analyzer.d.ts +72 -0
  14. package/dist/languages/java-analyzer.d.ts.map +1 -0
  15. package/dist/languages/java-analyzer.js +417 -0
  16. package/dist/languages/python-analyzer.d.ts +70 -0
  17. package/dist/languages/python-analyzer.d.ts.map +1 -0
  18. package/dist/languages/python-analyzer.js +425 -0
  19. package/dist/license/compatibility-matrix.d.ts +28 -0
  20. package/dist/license/compatibility-matrix.d.ts.map +1 -0
  21. package/dist/license/compatibility-matrix.js +323 -0
  22. package/dist/license/engine.d.ts +77 -0
  23. package/dist/license/engine.d.ts.map +1 -0
  24. package/dist/license/engine.js +264 -0
  25. package/dist/license/index.d.ts +6 -0
  26. package/dist/license/index.d.ts.map +1 -0
  27. package/dist/license/index.js +21 -0
  28. package/dist/sbom/generator.d.ts +108 -0
  29. package/dist/sbom/generator.d.ts.map +1 -0
  30. package/dist/sbom/generator.js +271 -0
  31. package/dist/sbom/index.d.ts +5 -0
  32. package/dist/sbom/index.d.ts.map +1 -0
  33. package/dist/sbom/index.js +20 -0
  34. package/dist/secrets/guardian.d.ts +113 -0
  35. package/dist/secrets/guardian.d.ts.map +1 -0
  36. package/dist/secrets/guardian.js +334 -0
  37. package/dist/secrets/index.d.ts +10 -0
  38. package/dist/secrets/index.d.ts.map +1 -0
  39. package/dist/secrets/index.js +30 -0
  40. package/dist/secrets/patterns.d.ts +42 -0
  41. package/dist/secrets/patterns.d.ts.map +1 -0
  42. package/dist/secrets/patterns.js +165 -0
  43. package/dist/secrets/pre-commit.d.ts +39 -0
  44. package/dist/secrets/pre-commit.d.ts.map +1 -0
  45. package/dist/secrets/pre-commit.js +127 -0
  46. package/dist/secrets/vault-integration.d.ts +83 -0
  47. package/dist/secrets/vault-integration.d.ts.map +1 -0
  48. package/dist/secrets/vault-integration.js +295 -0
  49. package/dist/secrets/vault-providers.d.ts +110 -0
  50. package/dist/secrets/vault-providers.d.ts.map +1 -0
  51. package/dist/secrets/vault-providers.js +417 -0
  52. package/dist/supply-chain/detector.d.ts +80 -0
  53. package/dist/supply-chain/detector.d.ts.map +1 -0
  54. package/dist/supply-chain/detector.js +168 -0
  55. package/dist/supply-chain/index.d.ts +11 -0
  56. package/dist/supply-chain/index.d.ts.map +1 -0
  57. package/dist/supply-chain/index.js +26 -0
  58. package/dist/supply-chain/malicious-db.d.ts +41 -0
  59. package/dist/supply-chain/malicious-db.d.ts.map +1 -0
  60. package/dist/supply-chain/malicious-db.js +82 -0
  61. package/dist/supply-chain/script-analyzer.d.ts +54 -0
  62. package/dist/supply-chain/script-analyzer.d.ts.map +1 -0
  63. package/dist/supply-chain/script-analyzer.js +160 -0
  64. package/dist/supply-chain/typosquat.d.ts +58 -0
  65. package/dist/supply-chain/typosquat.d.ts.map +1 -0
  66. package/dist/supply-chain/typosquat.js +257 -0
  67. package/dist/supply-chain/vulnerability-db.d.ts +114 -0
  68. package/dist/supply-chain/vulnerability-db.d.ts.map +1 -0
  69. package/dist/supply-chain/vulnerability-db.js +310 -0
  70. package/package.json +34 -0
  71. package/src/__tests__/license/engine.test.ts +250 -0
  72. package/src/__tests__/supply-chain/typosquat.test.ts +191 -0
  73. package/src/attack-surface/analyzer.ts +152 -0
  74. package/src/attack-surface/index.ts +5 -0
  75. package/src/index.ts +21 -0
  76. package/src/languages/index.ts +91 -0
  77. package/src/languages/java-analyzer.ts +490 -0
  78. package/src/languages/python-analyzer.ts +498 -0
  79. package/src/license/compatibility-matrix.ts +366 -0
  80. package/src/license/engine.ts +345 -0
  81. package/src/license/index.ts +6 -0
  82. package/src/sbom/generator.ts +355 -0
  83. package/src/sbom/index.ts +5 -0
  84. package/src/secrets/guardian.ts +448 -0
  85. package/src/secrets/index.ts +10 -0
  86. package/src/secrets/patterns.ts +186 -0
  87. package/src/secrets/pre-commit.ts +158 -0
  88. package/src/secrets/vault-integration.ts +360 -0
  89. package/src/secrets/vault-providers.ts +446 -0
  90. package/src/supply-chain/detector.ts +252 -0
  91. package/src/supply-chain/index.ts +11 -0
  92. package/src/supply-chain/malicious-db.ts +103 -0
  93. package/src/supply-chain/script-analyzer.ts +194 -0
  94. package/src/supply-chain/typosquat.ts +302 -0
  95. package/src/supply-chain/vulnerability-db.ts +386 -0
@@ -0,0 +1,417 @@
1
+ "use strict";
2
+ /**
3
+ * Vault Providers
4
+ *
5
+ * Real implementations for secret vault integrations:
6
+ * - AWS Secrets Manager
7
+ * - HashiCorp Vault
8
+ * - Azure Key Vault
9
+ * - GCP Secret Manager
10
+ */
11
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ var desc = Object.getOwnPropertyDescriptor(m, k);
14
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
+ desc = { enumerable: true, get: function() { return m[k]; } };
16
+ }
17
+ Object.defineProperty(o, k2, desc);
18
+ }) : (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ o[k2] = m[k];
21
+ }));
22
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
24
+ }) : function(o, v) {
25
+ o["default"] = v;
26
+ });
27
+ var __importStar = (this && this.__importStar) || (function () {
28
+ var ownKeys = function(o) {
29
+ ownKeys = Object.getOwnPropertyNames || function (o) {
30
+ var ar = [];
31
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
32
+ return ar;
33
+ };
34
+ return ownKeys(o);
35
+ };
36
+ return function (mod) {
37
+ if (mod && mod.__esModule) return mod;
38
+ var result = {};
39
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
40
+ __setModuleDefault(result, mod);
41
+ return result;
42
+ };
43
+ })();
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.LocalEnvProvider = exports.GCPSecretManagerProvider = exports.AzureKeyVaultProvider = exports.HashiCorpVaultProvider = exports.AWSSecretsManagerProvider = void 0;
46
+ exports.createVaultProvider = createVaultProvider;
47
+ /**
48
+ * AWS Secrets Manager Provider
49
+ */
50
+ class AWSSecretsManagerProvider {
51
+ name = 'AWS Secrets Manager';
52
+ client;
53
+ region;
54
+ constructor(config) {
55
+ this.region = config.region || 'us-east-1';
56
+ }
57
+ async getClient() {
58
+ if (!this.client) {
59
+ const { SecretsManagerClient } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-secrets-manager')));
60
+ this.client = new SecretsManagerClient({ region: this.region });
61
+ }
62
+ return this.client;
63
+ }
64
+ async createSecret(name, value) {
65
+ const client = await this.getClient();
66
+ const { CreateSecretCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-secrets-manager')));
67
+ try {
68
+ const result = await client.send(new CreateSecretCommand({
69
+ Name: name,
70
+ SecretString: value,
71
+ Description: 'Migrated by Guardrail AI',
72
+ }));
73
+ return result.ARN || name;
74
+ }
75
+ catch (error) {
76
+ if (error.name === 'ResourceExistsException') {
77
+ const { PutSecretValueCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-secrets-manager')));
78
+ await client.send(new PutSecretValueCommand({
79
+ SecretId: name,
80
+ SecretString: value,
81
+ }));
82
+ return name;
83
+ }
84
+ throw error;
85
+ }
86
+ }
87
+ async getSecret(name) {
88
+ const client = await this.getClient();
89
+ const { GetSecretValueCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-secrets-manager')));
90
+ try {
91
+ const result = await client.send(new GetSecretValueCommand({ SecretId: name }));
92
+ return result.SecretString || null;
93
+ }
94
+ catch (error) {
95
+ if (error.name === 'ResourceNotFoundException') {
96
+ return null;
97
+ }
98
+ throw error;
99
+ }
100
+ }
101
+ async deleteSecret(name) {
102
+ const client = await this.getClient();
103
+ const { DeleteSecretCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-secrets-manager')));
104
+ try {
105
+ await client.send(new DeleteSecretCommand({
106
+ SecretId: name,
107
+ ForceDeleteWithoutRecovery: false,
108
+ }));
109
+ return true;
110
+ }
111
+ catch (error) {
112
+ return false;
113
+ }
114
+ }
115
+ async listSecrets() {
116
+ const client = await this.getClient();
117
+ const { ListSecretsCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-secrets-manager')));
118
+ const result = await client.send(new ListSecretsCommand({}));
119
+ return (result.SecretList || []).map((s) => s.Name).filter(Boolean);
120
+ }
121
+ async testConnection() {
122
+ try {
123
+ await this.listSecrets();
124
+ return true;
125
+ }
126
+ catch (error) {
127
+ return false;
128
+ }
129
+ }
130
+ }
131
+ exports.AWSSecretsManagerProvider = AWSSecretsManagerProvider;
132
+ /**
133
+ * HashiCorp Vault Provider
134
+ */
135
+ class HashiCorpVaultProvider {
136
+ name = 'HashiCorp Vault';
137
+ client;
138
+ endpoint;
139
+ token;
140
+ mountPath;
141
+ constructor(config) {
142
+ this.endpoint = config.endpoint || 'http://127.0.0.1:8200';
143
+ this.token = config.credentials?.token || process.env['VAULT_TOKEN'] || '';
144
+ this.mountPath = 'secret';
145
+ }
146
+ async getClient() {
147
+ if (!this.client) {
148
+ const vault = (await Promise.resolve().then(() => __importStar(require('node-vault')))).default;
149
+ this.client = vault({
150
+ endpoint: this.endpoint,
151
+ token: this.token,
152
+ });
153
+ }
154
+ return this.client;
155
+ }
156
+ async createSecret(name, value) {
157
+ const client = await this.getClient();
158
+ const path = `${this.mountPath}/data/${name}`;
159
+ await client.write(path, {
160
+ data: { value },
161
+ metadata: { created_by: 'Guardrail-ai' },
162
+ });
163
+ return path;
164
+ }
165
+ async getSecret(name) {
166
+ const client = await this.getClient();
167
+ const path = `${this.mountPath}/data/${name}`;
168
+ try {
169
+ const result = await client.read(path);
170
+ return result?.data?.data?.value || null;
171
+ }
172
+ catch (error) {
173
+ if (error.response?.statusCode === 404) {
174
+ return null;
175
+ }
176
+ throw error;
177
+ }
178
+ }
179
+ async deleteSecret(name) {
180
+ const client = await this.getClient();
181
+ const path = `${this.mountPath}/metadata/${name}`;
182
+ try {
183
+ await client.delete(path);
184
+ return true;
185
+ }
186
+ catch (error) {
187
+ return false;
188
+ }
189
+ }
190
+ async listSecrets() {
191
+ const client = await this.getClient();
192
+ const path = `${this.mountPath}/metadata`;
193
+ try {
194
+ const result = await client.list(path);
195
+ return result?.data?.keys || [];
196
+ }
197
+ catch (error) {
198
+ return [];
199
+ }
200
+ }
201
+ async testConnection() {
202
+ try {
203
+ const client = await this.getClient();
204
+ await client.health();
205
+ return true;
206
+ }
207
+ catch (error) {
208
+ return false;
209
+ }
210
+ }
211
+ }
212
+ exports.HashiCorpVaultProvider = HashiCorpVaultProvider;
213
+ /**
214
+ * Azure Key Vault Provider
215
+ */
216
+ class AzureKeyVaultProvider {
217
+ name = 'Azure Key Vault';
218
+ client;
219
+ vaultUrl;
220
+ constructor(config) {
221
+ this.vaultUrl = config.endpoint || '';
222
+ if (!this.vaultUrl) {
223
+ throw new Error('Azure Key Vault URL is required');
224
+ }
225
+ }
226
+ async getClient() {
227
+ if (!this.client) {
228
+ const { SecretClient } = await Promise.resolve().then(() => __importStar(require('@azure/keyvault-secrets')));
229
+ const { DefaultAzureCredential } = await Promise.resolve().then(() => __importStar(require('@azure/identity')));
230
+ const credential = new DefaultAzureCredential();
231
+ this.client = new SecretClient(this.vaultUrl, credential);
232
+ }
233
+ return this.client;
234
+ }
235
+ async createSecret(name, value) {
236
+ const client = await this.getClient();
237
+ const sanitizedName = name.replace(/[^a-zA-Z0-9-]/g, '-');
238
+ const result = await client.setSecret(sanitizedName, value, {
239
+ tags: { createdBy: 'Guardrail-ai' },
240
+ });
241
+ return result.properties.id || sanitizedName;
242
+ }
243
+ async getSecret(name) {
244
+ const client = await this.getClient();
245
+ const sanitizedName = name.replace(/[^a-zA-Z0-9-]/g, '-');
246
+ try {
247
+ const result = await client.getSecret(sanitizedName);
248
+ return result.value || null;
249
+ }
250
+ catch (error) {
251
+ if (error.code === 'SecretNotFound') {
252
+ return null;
253
+ }
254
+ throw error;
255
+ }
256
+ }
257
+ async deleteSecret(name) {
258
+ const client = await this.getClient();
259
+ const sanitizedName = name.replace(/[^a-zA-Z0-9-]/g, '-');
260
+ try {
261
+ await client.beginDeleteSecret(sanitizedName);
262
+ return true;
263
+ }
264
+ catch (error) {
265
+ return false;
266
+ }
267
+ }
268
+ async listSecrets() {
269
+ const client = await this.getClient();
270
+ const secrets = [];
271
+ for await (const secretProperties of client.listPropertiesOfSecrets()) {
272
+ secrets.push(secretProperties.name);
273
+ }
274
+ return secrets;
275
+ }
276
+ async testConnection() {
277
+ try {
278
+ await this.listSecrets();
279
+ return true;
280
+ }
281
+ catch (error) {
282
+ return false;
283
+ }
284
+ }
285
+ }
286
+ exports.AzureKeyVaultProvider = AzureKeyVaultProvider;
287
+ /**
288
+ * GCP Secret Manager Provider
289
+ */
290
+ class GCPSecretManagerProvider {
291
+ name = 'GCP Secret Manager';
292
+ client;
293
+ projectId;
294
+ constructor(config) {
295
+ this.projectId = config.projectId || process.env['GOOGLE_CLOUD_PROJECT'] || '';
296
+ if (!this.projectId) {
297
+ throw new Error('GCP Project ID is required');
298
+ }
299
+ }
300
+ async getClient() {
301
+ if (!this.client) {
302
+ const { SecretManagerServiceClient } = await Promise.resolve().then(() => __importStar(require('@google-cloud/secret-manager')));
303
+ this.client = new SecretManagerServiceClient();
304
+ }
305
+ return this.client;
306
+ }
307
+ async createSecret(name, value) {
308
+ const client = await this.getClient();
309
+ const parent = `projects/${this.projectId}`;
310
+ const sanitizedName = name.replace(/[^a-zA-Z0-9_-]/g, '_');
311
+ try {
312
+ await client.createSecret({
313
+ parent,
314
+ secretId: sanitizedName,
315
+ secret: {
316
+ replication: { automatic: {} },
317
+ labels: { created_by: 'Guardrail-ai' },
318
+ },
319
+ });
320
+ }
321
+ catch (error) {
322
+ if (error.code !== 6) {
323
+ throw error;
324
+ }
325
+ }
326
+ const secretName = `${parent}/secrets/${sanitizedName}`;
327
+ await client.addSecretVersion({
328
+ parent: secretName,
329
+ payload: { data: Buffer.from(value, 'utf8') },
330
+ });
331
+ return secretName;
332
+ }
333
+ async getSecret(name) {
334
+ const client = await this.getClient();
335
+ const sanitizedName = name.replace(/[^a-zA-Z0-9_-]/g, '_');
336
+ const secretName = `projects/${this.projectId}/secrets/${sanitizedName}/versions/latest`;
337
+ try {
338
+ const [version] = await client.accessSecretVersion({ name: secretName });
339
+ return version.payload?.data?.toString() || null;
340
+ }
341
+ catch (error) {
342
+ if (error.code === 5) {
343
+ return null;
344
+ }
345
+ throw error;
346
+ }
347
+ }
348
+ async deleteSecret(name) {
349
+ const client = await this.getClient();
350
+ const sanitizedName = name.replace(/[^a-zA-Z0-9_-]/g, '_');
351
+ const secretName = `projects/${this.projectId}/secrets/${sanitizedName}`;
352
+ try {
353
+ await client.deleteSecret({ name: secretName });
354
+ return true;
355
+ }
356
+ catch (error) {
357
+ return false;
358
+ }
359
+ }
360
+ async listSecrets() {
361
+ const client = await this.getClient();
362
+ const parent = `projects/${this.projectId}`;
363
+ const [secrets] = await client.listSecrets({ parent });
364
+ return secrets.map((s) => s.name?.split('/').pop()).filter(Boolean);
365
+ }
366
+ async testConnection() {
367
+ try {
368
+ await this.listSecrets();
369
+ return true;
370
+ }
371
+ catch (error) {
372
+ return false;
373
+ }
374
+ }
375
+ }
376
+ exports.GCPSecretManagerProvider = GCPSecretManagerProvider;
377
+ /**
378
+ * Factory function to create vault provider
379
+ */
380
+ function createVaultProvider(config) {
381
+ switch (config.type) {
382
+ case 'aws_secrets_manager':
383
+ return new AWSSecretsManagerProvider(config);
384
+ case 'hashicorp_vault':
385
+ return new HashiCorpVaultProvider(config);
386
+ case 'azure_keyvault':
387
+ return new AzureKeyVaultProvider(config);
388
+ case 'gcp_secret_manager':
389
+ return new GCPSecretManagerProvider(config);
390
+ default:
391
+ throw new Error(`Unsupported vault type: ${config.type}`);
392
+ }
393
+ }
394
+ /**
395
+ * Local environment provider (for development/testing)
396
+ */
397
+ class LocalEnvProvider {
398
+ name = 'Local Environment';
399
+ secrets = new Map();
400
+ async createSecret(name, value) {
401
+ this.secrets.set(name, value);
402
+ return `local://${name}`;
403
+ }
404
+ async getSecret(name) {
405
+ return this.secrets.get(name) || process.env[name] || null;
406
+ }
407
+ async deleteSecret(name) {
408
+ return this.secrets.delete(name);
409
+ }
410
+ async listSecrets() {
411
+ return Array.from(this.secrets.keys());
412
+ }
413
+ async testConnection() {
414
+ return true;
415
+ }
416
+ }
417
+ exports.LocalEnvProvider = LocalEnvProvider;
@@ -0,0 +1,80 @@
1
+ import { TyposquatResult } from "./typosquat";
2
+ import { ScriptAnalysisResult } from "./script-analyzer";
3
+ /**
4
+ * Package analysis result
5
+ */
6
+ export interface PackageAnalysisResult {
7
+ packageName: string;
8
+ version: string;
9
+ registry: string;
10
+ riskScore: number;
11
+ threats: Threat[];
12
+ isMalicious: boolean;
13
+ isTyposquat: boolean;
14
+ isDeprecated: boolean;
15
+ typosquatResult?: TyposquatResult;
16
+ scriptAnalysis?: ScriptAnalysisResult[];
17
+ license?: string;
18
+ maintainerRisk?: MaintainerRisk;
19
+ }
20
+ export interface Threat {
21
+ type: string;
22
+ severity: "low" | "medium" | "high" | "critical";
23
+ description: string;
24
+ }
25
+ export interface MaintainerRisk {
26
+ accountAge: number;
27
+ packageCount: number;
28
+ suspiciousActivity: boolean;
29
+ riskLevel: "low" | "medium" | "high";
30
+ }
31
+ /**
32
+ * SBOM (Software Bill of Materials)
33
+ */
34
+ export interface SBOM {
35
+ id?: string;
36
+ projectId: string;
37
+ version: number;
38
+ format: "CycloneDX" | "SPDX";
39
+ specVersion: string;
40
+ components: SBOMComponent[];
41
+ generatedAt: Date;
42
+ }
43
+ export interface SBOMComponent {
44
+ type: "library" | "application" | "framework";
45
+ name: string;
46
+ version: string;
47
+ purl: string;
48
+ licenses?: string[];
49
+ hashes?: {
50
+ algorithm: string;
51
+ value: string;
52
+ }[];
53
+ dependencies?: string[];
54
+ }
55
+ /**
56
+ * Supply Chain Attack Detector
57
+ */
58
+ export declare class SupplyChainDetector {
59
+ /**
60
+ * Detect typosquatting
61
+ */
62
+ detectTyposquatting(packageName: string): Promise<TyposquatResult>;
63
+ /**
64
+ * Detect dependency confusion
65
+ */
66
+ detectDependencyConfusion(_packageName: string, internalRegistry?: string): Promise<{
67
+ isDependencyConfusion: boolean;
68
+ reason: string;
69
+ }>;
70
+ /**
71
+ * Full package analysis
72
+ */
73
+ analyzePackage(packageName: string, version: string, projectId: string): Promise<PackageAnalysisResult>;
74
+ /**
75
+ * Generate SBOM (CycloneDX format)
76
+ */
77
+ generateSBOM(projectPath: string, projectId: string): Promise<SBOM>;
78
+ }
79
+ export declare const supplyChainDetector: SupplyChainDetector;
80
+ //# sourceMappingURL=detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detector.d.ts","sourceRoot":"","sources":["../../src/supply-chain/detector.ts"],"names":[],"mappings":"AACA,OAAO,EAAqB,eAAe,EAAE,MAAM,aAAa,CAAC;AAEjE,OAAO,EAAkB,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAIzE;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,cAAc,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;IACjD,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,SAAS,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,IAAI;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,WAAW,GAAG,MAAM,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,WAAW,EAAE,IAAI,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,SAAS,GAAG,aAAa,GAAG,WAAW,CAAC;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAChD,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED;;GAEG;AACH,qBAAa,mBAAmB;IAC9B;;OAEG;IACG,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAIxE;;OAEG;IACG,yBAAyB,CAC7B,YAAY,EAAE,MAAM,EACpB,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,CAAC;QAAE,qBAAqB,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAoB9D;;OAEG;IACG,cAAc,CAClB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,qBAAqB,CAAC;IAiFjC;;OAEG;IACG,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CA2D1E;AAGD,eAAO,MAAM,mBAAmB,qBAA4B,CAAC"}
@@ -0,0 +1,168 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.supplyChainDetector = exports.SupplyChainDetector = void 0;
4
+ const database_1 = require("@guardrail/database");
5
+ const typosquat_1 = require("./typosquat");
6
+ const malicious_db_1 = require("./malicious-db");
7
+ const script_analyzer_1 = require("./script-analyzer");
8
+ const fs_1 = require("fs");
9
+ const path_1 = require("path");
10
+ /**
11
+ * Supply Chain Attack Detector
12
+ */
13
+ class SupplyChainDetector {
14
+ /**
15
+ * Detect typosquatting
16
+ */
17
+ async detectTyposquatting(packageName) {
18
+ return typosquat_1.typosquatDetector.detectTyposquatting(packageName);
19
+ }
20
+ /**
21
+ * Detect dependency confusion
22
+ */
23
+ async detectDependencyConfusion(_packageName, internalRegistry) {
24
+ // Check if package exists in both public and internal registries
25
+ // This is a simplified implementation
26
+ if (!internalRegistry) {
27
+ return {
28
+ isDependencyConfusion: false,
29
+ reason: "No internal registry configured",
30
+ };
31
+ }
32
+ // In production, this would check both registries
33
+ // and compare versions, publish dates, etc.
34
+ return {
35
+ isDependencyConfusion: false,
36
+ reason: "Package only found in public registry",
37
+ };
38
+ }
39
+ /**
40
+ * Full package analysis
41
+ */
42
+ async analyzePackage(packageName, version, projectId) {
43
+ const threats = [];
44
+ let riskScore = 0;
45
+ // Check for typosquatting
46
+ const typosquatResult = await this.detectTyposquatting(packageName);
47
+ const isTyposquat = typosquatResult.isTyposquat;
48
+ if (isTyposquat) {
49
+ threats.push({
50
+ type: "typosquatting",
51
+ severity: "high",
52
+ description: `Possible typosquatting of ${typosquatResult.targetPackage}`,
53
+ });
54
+ riskScore += 40;
55
+ }
56
+ // Check against malicious database
57
+ const maliciousCheck = await malicious_db_1.maliciousPackageDB.checkPackage(packageName, version);
58
+ const isMalicious = maliciousCheck.isMalicious;
59
+ if (isMalicious) {
60
+ for (const match of maliciousCheck.matches) {
61
+ threats.push({
62
+ type: "known_malicious",
63
+ severity: match.severity,
64
+ description: match.reason,
65
+ });
66
+ riskScore += 50;
67
+ }
68
+ }
69
+ // Analyze scripts
70
+ const scriptAnalysis = await script_analyzer_1.scriptAnalyzer.analyzeScripts(packageName, version);
71
+ for (const analysis of scriptAnalysis) {
72
+ if (analysis.isSuspicious) {
73
+ threats.push({
74
+ type: "suspicious_script",
75
+ severity: "high",
76
+ description: `Suspicious script: ${analysis.scriptName}`,
77
+ });
78
+ riskScore += analysis.riskScore * 0.5;
79
+ }
80
+ }
81
+ // Save to database
82
+ await database_1.prisma.dependencyAnalysis.create({
83
+ data: {
84
+ projectId,
85
+ packageName,
86
+ version,
87
+ registry: "npm",
88
+ isMalicious,
89
+ isTyposquat,
90
+ isDeprecated: false,
91
+ riskScore: Math.min(100, riskScore),
92
+ threats: JSON.parse(JSON.stringify(threats)),
93
+ },
94
+ });
95
+ return {
96
+ packageName,
97
+ version,
98
+ registry: "npm",
99
+ riskScore: Math.min(100, riskScore),
100
+ threats,
101
+ isMalicious,
102
+ isTyposquat,
103
+ isDeprecated: false,
104
+ typosquatResult: isTyposquat ? typosquatResult : undefined,
105
+ scriptAnalysis,
106
+ };
107
+ }
108
+ /**
109
+ * Generate SBOM (CycloneDX format)
110
+ */
111
+ async generateSBOM(projectPath, projectId) {
112
+ const components = [];
113
+ try {
114
+ // Read package.json
115
+ const packageJsonPath = (0, path_1.join)(projectPath, "package.json");
116
+ const packageJson = JSON.parse((0, fs_1.readFileSync)(packageJsonPath, "utf-8"));
117
+ // Extract dependencies
118
+ const deps = {
119
+ ...packageJson.dependencies,
120
+ ...packageJson.devDependencies,
121
+ };
122
+ for (const [name, version] of Object.entries(deps)) {
123
+ components.push({
124
+ type: "library",
125
+ name,
126
+ version: version,
127
+ purl: `pkg:npm/${name}@${version}`,
128
+ });
129
+ }
130
+ }
131
+ catch (error) {
132
+ // Handle error
133
+ }
134
+ const sbom = {
135
+ id: `sbom_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
136
+ projectId,
137
+ version: 1,
138
+ format: "CycloneDX",
139
+ specVersion: "1.4",
140
+ components,
141
+ generatedAt: new Date(),
142
+ };
143
+ // @ts-ignore - SBOM model exists in schema, Prisma client may need regeneration
144
+ const savedSBOM = await database_1.prisma.sBOM.create({
145
+ data: {
146
+ id: sbom.id,
147
+ projectId,
148
+ version: sbom.version,
149
+ format: sbom.format,
150
+ specVersion: sbom.specVersion,
151
+ components: JSON.parse(JSON.stringify(components)),
152
+ generatedAt: sbom.generatedAt,
153
+ },
154
+ });
155
+ return {
156
+ id: savedSBOM.id,
157
+ projectId: savedSBOM.projectId,
158
+ version: savedSBOM.version,
159
+ format: savedSBOM.format,
160
+ specVersion: savedSBOM.specVersion,
161
+ components: savedSBOM.components,
162
+ generatedAt: savedSBOM.generatedAt,
163
+ };
164
+ }
165
+ }
166
+ exports.SupplyChainDetector = SupplyChainDetector;
167
+ // Export singleton
168
+ exports.supplyChainDetector = new SupplyChainDetector();
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Supply Chain Attack Detection
3
+ *
4
+ * Detects typosquatting, malicious packages, and generates SBOMs
5
+ */
6
+ export * from './detector';
7
+ export * from './typosquat';
8
+ export * from './malicious-db';
9
+ export * from './script-analyzer';
10
+ export * from './vulnerability-db';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/supply-chain/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC"}