supply-chain-guard 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.
@@ -0,0 +1,246 @@
1
+ "use strict";
2
+ /**
3
+ * Solana C2 wallet monitor
4
+ *
5
+ * Monitors Solana wallet addresses for transactions containing memo instructions.
6
+ * GlassWorm and similar campaigns encode C2 URLs as Solana transaction memos,
7
+ * making the blockchain an uncensorable command-and-control channel.
8
+ */
9
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ var desc = Object.getOwnPropertyDescriptor(m, k);
12
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
+ desc = { enumerable: true, get: function() { return m[k]; } };
14
+ }
15
+ Object.defineProperty(o, k2, desc);
16
+ }) : (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ o[k2] = m[k];
19
+ }));
20
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
22
+ }) : function(o, v) {
23
+ o["default"] = v;
24
+ });
25
+ var __importStar = (this && this.__importStar) || (function () {
26
+ var ownKeys = function(o) {
27
+ ownKeys = Object.getOwnPropertyNames || function (o) {
28
+ var ar = [];
29
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
30
+ return ar;
31
+ };
32
+ return ownKeys(o);
33
+ };
34
+ return function (mod) {
35
+ if (mod && mod.__esModule) return mod;
36
+ var result = {};
37
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
38
+ __setModuleDefault(result, mod);
39
+ return result;
40
+ };
41
+ })();
42
+ Object.defineProperty(exports, "__esModule", { value: true });
43
+ exports.monitorWallet = monitorWallet;
44
+ exports.checkWallet = checkWallet;
45
+ exports.formatAlert = formatAlert;
46
+ const https = __importStar(require("node:https"));
47
+ const SOLANA_RPC = "https://api.mainnet-beta.solana.com";
48
+ const MEMO_PROGRAM_ID = "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr";
49
+ /**
50
+ * Monitor a Solana wallet for C2 memo transactions.
51
+ * Runs continuously until stopped.
52
+ */
53
+ async function monitorWallet(options, onAlert) {
54
+ const { address, interval, limit } = options;
55
+ let lastSignature = null;
56
+ console.log(`\n Monitoring Solana wallet: ${address}`);
57
+ console.log(` Polling interval: ${interval}s | Checking last ${limit} transactions`);
58
+ console.log(` Press Ctrl+C to stop\n`);
59
+ // Initial fetch to set baseline
60
+ const initial = await getRecentSignatures(address, limit);
61
+ if (initial.length > 0) {
62
+ lastSignature = initial[0]?.signature ?? null;
63
+ console.log(` Baseline set: ${initial.length} existing transactions`);
64
+ console.log(` Latest: ${lastSignature}\n`);
65
+ }
66
+ // Poll loop
67
+ const poll = async () => {
68
+ try {
69
+ const signatures = await getRecentSignatures(address, limit);
70
+ // Find new transactions since last check
71
+ const newSigs = [];
72
+ for (const sig of signatures) {
73
+ if (sig.signature === lastSignature)
74
+ break;
75
+ newSigs.push(sig);
76
+ }
77
+ if (newSigs.length > 0 && lastSignature !== null) {
78
+ console.log(` [${new Date().toISOString()}] ${newSigs.length} new transaction(s)`);
79
+ for (const sig of newSigs) {
80
+ const detail = await getTransactionDetail(sig.signature);
81
+ if (detail && detail.memos.length > 0) {
82
+ for (const memo of detail.memos) {
83
+ const alert = {
84
+ timestamp: new Date().toISOString(),
85
+ wallet: address,
86
+ signature: sig.signature,
87
+ memo,
88
+ decodedUrls: extractUrls(memo),
89
+ blockTime: detail.blockTime,
90
+ };
91
+ onAlert(alert);
92
+ }
93
+ }
94
+ }
95
+ lastSignature = newSigs[0]?.signature ?? lastSignature;
96
+ }
97
+ }
98
+ catch (err) {
99
+ const message = err instanceof Error ? err.message : String(err);
100
+ console.error(` [${new Date().toISOString()}] Poll error: ${message}`);
101
+ }
102
+ // Schedule next poll
103
+ setTimeout(() => void poll(), interval * 1000);
104
+ };
105
+ await poll();
106
+ }
107
+ /**
108
+ * One-shot check: get recent transactions and check for memos.
109
+ */
110
+ async function checkWallet(address, limit = 20) {
111
+ const signatures = await getRecentSignatures(address, limit);
112
+ const results = [];
113
+ for (const sig of signatures) {
114
+ const detail = await getTransactionDetail(sig.signature);
115
+ if (detail && detail.memos.length > 0) {
116
+ results.push(detail);
117
+ }
118
+ }
119
+ return results;
120
+ }
121
+ /**
122
+ * Get recent transaction signatures for a wallet.
123
+ */
124
+ async function getRecentSignatures(address, limit) {
125
+ const response = await solanaRpc("getSignaturesForAddress", [
126
+ address,
127
+ { limit },
128
+ ]);
129
+ if (!Array.isArray(response))
130
+ return [];
131
+ return response.map((tx) => ({ signature: tx.signature }));
132
+ }
133
+ /**
134
+ * Get full transaction detail and extract memo instructions.
135
+ */
136
+ async function getTransactionDetail(signature) {
137
+ const response = await solanaRpc("getTransaction", [
138
+ signature,
139
+ { encoding: "jsonParsed", maxSupportedTransactionVersion: 0 },
140
+ ]);
141
+ if (!response)
142
+ return null;
143
+ const memos = [];
144
+ const tx = response;
145
+ // Check main instructions
146
+ const instructions = tx.transaction?.message?.instructions ?? [];
147
+ for (const ix of instructions) {
148
+ if (ix.programId === MEMO_PROGRAM_ID) {
149
+ const memoText = ix.parsed ?? ix.data ?? "";
150
+ if (memoText)
151
+ memos.push(memoText);
152
+ }
153
+ }
154
+ // Check inner instructions
155
+ const innerInstructions = tx.meta?.innerInstructions ?? [];
156
+ for (const inner of innerInstructions) {
157
+ for (const ix of inner.instructions ?? []) {
158
+ if (ix.programId === MEMO_PROGRAM_ID) {
159
+ const memoText = ix.parsed ?? ix.data ?? "";
160
+ if (memoText)
161
+ memos.push(memoText);
162
+ }
163
+ }
164
+ }
165
+ return {
166
+ signature,
167
+ blockTime: tx.blockTime ?? null,
168
+ memos,
169
+ };
170
+ }
171
+ /**
172
+ * Make a JSON-RPC call to the Solana RPC endpoint.
173
+ */
174
+ function solanaRpc(method, params) {
175
+ const body = JSON.stringify({
176
+ jsonrpc: "2.0",
177
+ id: 1,
178
+ method,
179
+ params,
180
+ });
181
+ return new Promise((resolve, reject) => {
182
+ const url = new URL(SOLANA_RPC);
183
+ const req = https.request({
184
+ hostname: url.hostname,
185
+ port: url.port || 443,
186
+ path: url.pathname,
187
+ method: "POST",
188
+ headers: {
189
+ "Content-Type": "application/json",
190
+ "Content-Length": Buffer.byteLength(body),
191
+ },
192
+ }, (res) => {
193
+ let data = "";
194
+ res.on("data", (chunk) => {
195
+ data += chunk.toString();
196
+ });
197
+ res.on("end", () => {
198
+ try {
199
+ const parsed = JSON.parse(data);
200
+ if (parsed.error) {
201
+ reject(new Error(`Solana RPC error: ${parsed.error.message}`));
202
+ return;
203
+ }
204
+ resolve(parsed.result);
205
+ }
206
+ catch {
207
+ reject(new Error("Failed to parse Solana RPC response"));
208
+ }
209
+ });
210
+ });
211
+ req.on("error", reject);
212
+ req.write(body);
213
+ req.end();
214
+ });
215
+ }
216
+ /**
217
+ * Extract URLs from a memo string.
218
+ */
219
+ function extractUrls(text) {
220
+ const urlRegex = /https?:\/\/[^\s"'<>]+/gi;
221
+ return text.match(urlRegex) ?? [];
222
+ }
223
+ /**
224
+ * Format a C2 alert for display.
225
+ */
226
+ function formatAlert(alert) {
227
+ const lines = [
228
+ "",
229
+ " ====================================",
230
+ " !! C2 MEMO DETECTED !!",
231
+ " ====================================",
232
+ ` Time: ${alert.timestamp}`,
233
+ ` Wallet: ${alert.wallet}`,
234
+ ` Signature: ${alert.signature}`,
235
+ ` Memo: ${alert.memo}`,
236
+ ];
237
+ if (alert.decodedUrls.length > 0) {
238
+ lines.push(` URLs: ${alert.decodedUrls.join(", ")}`);
239
+ }
240
+ if (alert.blockTime) {
241
+ lines.push(` Block: ${new Date(alert.blockTime * 1000).toISOString()}`);
242
+ }
243
+ lines.push(" ====================================", "");
244
+ return lines.join("\n");
245
+ }
246
+ //# sourceMappingURL=solana-monitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solana-monitor.js","sourceRoot":"","sources":["../src/solana-monitor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * supply-chain-guard type definitions
3
+ */
4
+ export type Severity = "critical" | "high" | "medium" | "low" | "info";
5
+ export interface Finding {
6
+ /** Unique rule identifier */
7
+ rule: string;
8
+ /** Human-readable description of the finding */
9
+ description: string;
10
+ /** Severity level */
11
+ severity: Severity;
12
+ /** File path relative to scan root (if applicable) */
13
+ file?: string;
14
+ /** Line number (if applicable) */
15
+ line?: number;
16
+ /** Matched content snippet */
17
+ match?: string;
18
+ /** Recommendation for remediation */
19
+ recommendation: string;
20
+ }
21
+ export interface ScanReport {
22
+ /** Tool name and version */
23
+ tool: string;
24
+ /** ISO 8601 timestamp */
25
+ timestamp: string;
26
+ /** What was scanned (path, URL, package name) */
27
+ target: string;
28
+ /** Type of scan performed */
29
+ scanType: "directory" | "github" | "npm" | "solana";
30
+ /** Duration in milliseconds */
31
+ durationMs: number;
32
+ /** All findings */
33
+ findings: Finding[];
34
+ /** Summary statistics */
35
+ summary: ScanSummary;
36
+ /** Overall risk score (0-100) */
37
+ score: number;
38
+ /** Risk level derived from score */
39
+ riskLevel: "clean" | "low" | "medium" | "high" | "critical";
40
+ /** Actionable recommendations */
41
+ recommendations: string[];
42
+ }
43
+ export interface ScanSummary {
44
+ totalFiles: number;
45
+ filesScanned: number;
46
+ critical: number;
47
+ high: number;
48
+ medium: number;
49
+ low: number;
50
+ info: number;
51
+ }
52
+ export interface ScanOptions {
53
+ /** Target path, URL, or package name */
54
+ target: string;
55
+ /** Output format */
56
+ format: "text" | "json" | "markdown";
57
+ /** Only report findings at or above this severity */
58
+ minSeverity?: Severity;
59
+ /** Exclude specific rules */
60
+ excludeRules?: string[];
61
+ /** Maximum directory depth */
62
+ maxDepth?: number;
63
+ }
64
+ export interface NpmPackageInfo {
65
+ name: string;
66
+ version: string;
67
+ description?: string;
68
+ scripts?: Record<string, string>;
69
+ dependencies?: Record<string, string>;
70
+ devDependencies?: Record<string, string>;
71
+ repository?: {
72
+ url?: string;
73
+ } | string;
74
+ author?: string | {
75
+ name?: string;
76
+ email?: string;
77
+ };
78
+ }
79
+ export interface SolanaTransaction {
80
+ signature: string;
81
+ blockTime: number | null;
82
+ memo: string | null;
83
+ err: unknown;
84
+ }
85
+ export interface SolanaMonitorOptions {
86
+ /** Wallet address to monitor */
87
+ address: string;
88
+ /** Polling interval in seconds */
89
+ interval: number;
90
+ /** Maximum number of transactions to check per poll */
91
+ limit: number;
92
+ /** Output format */
93
+ format: "text" | "json";
94
+ }
95
+ export interface PatternEntry {
96
+ /** Pattern name or identifier */
97
+ name: string;
98
+ /** Regex pattern string */
99
+ pattern: string;
100
+ /** What this pattern detects */
101
+ description: string;
102
+ /** Severity if matched */
103
+ severity: Severity;
104
+ /** Rule ID */
105
+ rule: string;
106
+ }
107
+ export declare const SEVERITY_SCORES: Record<Severity, number>;
108
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;AAEvE,MAAM,WAAW,OAAO;IACtB,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,WAAW,EAAE,MAAM,CAAC;IACpB,qBAAqB;IACrB,QAAQ,EAAE,QAAQ,CAAC;IACnB,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,6BAA6B;IAC7B,QAAQ,EAAE,WAAW,GAAG,QAAQ,GAAG,KAAK,GAAG,QAAQ,CAAC;IACpD,+BAA+B;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB;IACnB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,yBAAyB;IACzB,OAAO,EAAE,WAAW,CAAC;IACrB,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,SAAS,EAAE,OAAO,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;IAC5D,iCAAiC;IACjC,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,oBAAoB;IACpB,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU,CAAC;IACrC,qDAAqD;IACrD,WAAW,CAAC,EAAE,QAAQ,CAAC;IACvB,6BAA6B;IAC7B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,UAAU,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC;IACvC,MAAM,CAAC,EAAE,MAAM,GAAG;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACrD;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,GAAG,EAAE,OAAO,CAAC;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,gCAAgC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,kCAAkC;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAC;IACd,oBAAoB;IACpB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,2BAA2B;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,gCAAgC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,0BAA0B;IAC1B,QAAQ,EAAE,QAAQ,CAAC;IACnB,cAAc;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAMpD,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ /**
3
+ * supply-chain-guard type definitions
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SEVERITY_SCORES = void 0;
7
+ exports.SEVERITY_SCORES = {
8
+ critical: 25,
9
+ high: 15,
10
+ medium: 8,
11
+ low: 3,
12
+ info: 1,
13
+ };
14
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AA6GU,QAAA,eAAe,GAA6B;IACvD,QAAQ,EAAE,EAAE;IACZ,IAAI,EAAE,EAAE;IACR,MAAM,EAAE,CAAC;IACT,GAAG,EAAE,CAAC;IACN,IAAI,EAAE,CAAC;CACR,CAAC"}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "supply-chain-guard",
3
+ "version": "1.0.0",
4
+ "description": "Open-source supply-chain security scanner for npm, PyPI, and VS Code extensions. Detects GlassWorm and similar malware campaigns.",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "bin": {
8
+ "supply-chain-guard": "dist/cli.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "test": "vitest run",
13
+ "test:watch": "vitest",
14
+ "lint": "tsc --noEmit",
15
+ "prepublishOnly": "npm run build"
16
+ },
17
+ "keywords": [
18
+ "security",
19
+ "supply-chain",
20
+ "malware-detection",
21
+ "npm",
22
+ "glassworm",
23
+ "scanner",
24
+ "cli",
25
+ "github-action"
26
+ ],
27
+ "author": "Elvatis <emre.kohler@elvatis.com>",
28
+ "license": "Apache-2.0",
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "https://github.com/homeofe/supply-chain-guard.git"
32
+ },
33
+ "bugs": {
34
+ "url": "https://github.com/homeofe/supply-chain-guard/issues"
35
+ },
36
+ "homepage": "https://github.com/homeofe/supply-chain-guard#readme",
37
+ "engines": {
38
+ "node": ">=20.0.0"
39
+ },
40
+ "files": [
41
+ "dist/**/*",
42
+ "action.yml",
43
+ "README.md",
44
+ "LICENSE"
45
+ ],
46
+ "dependencies": {
47
+ "commander": "^13.1.0"
48
+ },
49
+ "devDependencies": {
50
+ "@types/node": "^22.13.0",
51
+ "typescript": "^5.7.0",
52
+ "vitest": "^3.0.0"
53
+ }
54
+ }