tangkal 1.1.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 (46) hide show
  1. package/README.md +62 -0
  2. package/dist/index.d.ts +3 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +4 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/src/analyzers/dependencies.d.ts +4 -0
  7. package/dist/src/analyzers/dependencies.d.ts.map +1 -0
  8. package/dist/src/analyzers/dependencies.js +79 -0
  9. package/dist/src/analyzers/dependencies.js.map +1 -0
  10. package/dist/src/analyzers/network.d.ts +17 -0
  11. package/dist/src/analyzers/network.d.ts.map +1 -0
  12. package/dist/src/analyzers/network.js +203 -0
  13. package/dist/src/analyzers/network.js.map +1 -0
  14. package/dist/src/analyzers/static-analysis.d.ts +18 -0
  15. package/dist/src/analyzers/static-analysis.d.ts.map +1 -0
  16. package/dist/src/analyzers/static-analysis.js +246 -0
  17. package/dist/src/analyzers/static-analysis.js.map +1 -0
  18. package/dist/src/cli.d.ts +2 -0
  19. package/dist/src/cli.d.ts.map +1 -0
  20. package/dist/src/cli.js +112 -0
  21. package/dist/src/cli.js.map +1 -0
  22. package/dist/src/config.d.ts +9 -0
  23. package/dist/src/config.d.ts.map +1 -0
  24. package/dist/src/config.js +40 -0
  25. package/dist/src/config.js.map +1 -0
  26. package/dist/src/scanner.d.ts +8 -0
  27. package/dist/src/scanner.d.ts.map +1 -0
  28. package/dist/src/scanner.js +115 -0
  29. package/dist/src/scanner.js.map +1 -0
  30. package/dist/src/utils/entropy.d.ts +7 -0
  31. package/dist/src/utils/entropy.d.ts.map +1 -0
  32. package/dist/src/utils/entropy.js +25 -0
  33. package/dist/src/utils/entropy.js.map +1 -0
  34. package/dist/src/utils/ignore.d.ts +3 -0
  35. package/dist/src/utils/ignore.d.ts.map +1 -0
  36. package/dist/src/utils/ignore.js +18 -0
  37. package/dist/src/utils/ignore.js.map +1 -0
  38. package/dist/src/utils/lockfile.d.ts +9 -0
  39. package/dist/src/utils/lockfile.d.ts.map +1 -0
  40. package/dist/src/utils/lockfile.js +143 -0
  41. package/dist/src/utils/lockfile.js.map +1 -0
  42. package/dist/src/utils/popular-packages.d.ts +2 -0
  43. package/dist/src/utils/popular-packages.d.ts.map +1 -0
  44. package/dist/src/utils/popular-packages.js +22 -0
  45. package/dist/src/utils/popular-packages.js.map +1 -0
  46. package/package.json +53 -0
package/README.md ADDED
@@ -0,0 +1,62 @@
1
+ # Tangkal 🛡️
2
+
3
+ **Tangkal** (Indonesian for "ward off" or "repel") is a lightweight, preventive security scanner designed to inspect cloned repositories *before* you run `npm install`.
4
+
5
+ It is specifically built to detect malicious patterns often found in "Job Scam" repositories, such as:
6
+ - **Obfuscated Code:** Base64 (atob, Buffer), Hexadecimal strings.
7
+ - **Dynamic Execution:** `eval`, `new Function`.
8
+ - **Hidden Network Calls:** Fetching payloads from remote URLs (e.g., JSON keepers).
9
+ - **Dangerous Lifecycle Scripts:** `preinstall`, `postinstall` in `package.json`.
10
+ - **Typosquatting:** Detects packages with names deceptively similar to popular libraries (e.g., `react-doom` vs `react-dom`).
11
+ - **Vulnerability Scanning:** Aggregates data from **OSV**, **Snyk**, and **Exploit DB** to report known vulnerabilities.
12
+
13
+ ## Installation
14
+
15
+ ### From Source
16
+ ```bash
17
+ git clone https://github.com/yourusername/tangkal.git
18
+ cd tangkal
19
+ npm install
20
+ npm link
21
+ ```
22
+
23
+ ## Usage
24
+
25
+ Run `tangkal` against any suspicious directory:
26
+
27
+ ```bash
28
+ tangkal ./path-to-suspicious-repo
29
+ ```
30
+
31
+ Or simply inside the directory:
32
+
33
+ ```bash
34
+ cd suspicious-repo
35
+ tangkal .
36
+ ```
37
+
38
+ ## Output Example
39
+
40
+ Tangkal separates findings into two clear categories: **Malicious Code** and **Vulnerable Packages**.
41
+
42
+ ```text
43
+ ====================================
44
+ ALERT: Malicious Code Detected
45
+ ====================================
46
+ File: src/utils.js
47
+ Line: 45
48
+ Suspicious pattern detected.
49
+ Code: new Function("return " + decodedPayload)()
50
+
51
+ ====================================
52
+ ALERT: Vulnerable Package
53
+ ====================================
54
+ [SOLUTION]: Upgrade lodash@4.17.15 to lodash@4.17.21 to fix.
55
+ [HIGH Severity] [https://osv.dev/vulnerability/GHSA-xxx] [Snyk: https://security.snyk.io/vuln?search=CVE-2021-23337]
56
+ lodash@4.17.15 Prototype Pollution
57
+ introduced by lodash@4.17.15
58
+ ```
59
+
60
+ ## Disclaimer
61
+
62
+ This tool uses heuristic pattern matching. It may produce false positives (e.g., in build scripts or test files) and cannot guarantee 100% safety. **Always review code manually if you are unsure.**
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { run } from './src/cli.js';
3
+ run();
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAEnC,GAAG,EAAE,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Finding } from './static-analysis.js';
2
+ export declare function checkTyposquatting(pkgJson: any): Promise<Finding[]>;
3
+ export declare function checkVulnerabilities(cwd: string): Promise<Finding[]>;
4
+ //# sourceMappingURL=dependencies.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependencies.d.ts","sourceRoot":"","sources":["../../../src/analyzers/dependencies.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAIpD,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CA4BzE;AAED,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CA2C1E"}
@@ -0,0 +1,79 @@
1
+ import levenshtein from 'fast-levenshtein';
2
+ import { getPopularPackages } from '../utils/popular-packages.js';
3
+ import { exec } from 'child_process';
4
+ import { promisify } from 'util';
5
+ const execAsync = promisify(exec);
6
+ export async function checkTyposquatting(pkgJson) {
7
+ const findings = [];
8
+ const allDeps = {
9
+ ...pkgJson.dependencies,
10
+ ...pkgJson.devDependencies
11
+ };
12
+ const popularPackages = await getPopularPackages();
13
+ for (const depName of Object.keys(allDeps)) {
14
+ for (const popular of popularPackages) {
15
+ if (depName === popular)
16
+ continue; // Exact match is fine
17
+ const distance = levenshtein.get(depName, popular);
18
+ const threshold = popular.length < 5 ? 1 : 2;
19
+ if (distance <= threshold) {
20
+ findings.push({
21
+ type: 'Typosquatting',
22
+ name: depName,
23
+ file: 'package.json', // Placeholder, caller handles file
24
+ severity: 'high',
25
+ description: `Package '${depName}' looks very similar to popular package '${popular}'.`
26
+ });
27
+ }
28
+ }
29
+ }
30
+ return findings;
31
+ }
32
+ export async function checkVulnerabilities(cwd) {
33
+ try {
34
+ const { stdout } = await execAsync('npm audit --json --audit-level=moderate', { cwd, maxBuffer: 10 * 1024 * 1024 });
35
+ const auditResult = JSON.parse(stdout);
36
+ const vulns = [];
37
+ if (auditResult.vulnerabilities) {
38
+ for (const [name, info] of Object.entries(auditResult.vulnerabilities)) {
39
+ if (info.severity === 'high' || info.severity === 'critical') {
40
+ vulns.push({
41
+ type: 'Vulnerability',
42
+ name,
43
+ file: 'package-lock.json',
44
+ severity: info.severity,
45
+ description: `Known vulnerability via ${info.via && info.via.join ? info.via.join(', ') : 'transitive dependency'}`
46
+ });
47
+ }
48
+ }
49
+ }
50
+ return vulns;
51
+ }
52
+ catch (error) {
53
+ if (error.stdout) {
54
+ try {
55
+ const auditResult = JSON.parse(error.stdout);
56
+ const vulns = [];
57
+ if (auditResult.vulnerabilities) {
58
+ for (const [name, info] of Object.entries(auditResult.vulnerabilities)) {
59
+ if (info.severity === 'high' || info.severity === 'critical') {
60
+ vulns.push({
61
+ type: 'Vulnerability',
62
+ name,
63
+ file: 'package-lock.json',
64
+ severity: info.severity,
65
+ description: `Known vulnerability (Severity: ${info.severity})`
66
+ });
67
+ }
68
+ }
69
+ }
70
+ return vulns;
71
+ }
72
+ catch (e) {
73
+ return [];
74
+ }
75
+ }
76
+ return [];
77
+ }
78
+ }
79
+ //# sourceMappingURL=dependencies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependencies.js","sourceRoot":"","sources":["../../../src/analyzers/dependencies.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { Finding } from './static-analysis.js';
2
+ import type { Dependency } from '../utils/lockfile.js';
3
+ /**
4
+ * Main entry point for network audit.
5
+ * Checks vulnerabilities for all packages.
6
+ * Checks reputation for a subset (or all if count is low) to avoid rate limiting.
7
+ */
8
+ export declare function auditDependencies(packages: Dependency[]): Promise<Finding[]>;
9
+ /**
10
+ * Checks the npm registry for package reputation (downloads, age).
11
+ */
12
+ export declare function checkReputation(pkgName: string): Promise<Finding[]>;
13
+ /**
14
+ * Checks for known vulnerabilities using OSV API (Batch Mode).
15
+ */
16
+ export declare function checkVulnerabilitiesBatch(packages: Dependency[]): Promise<Finding[]>;
17
+ //# sourceMappingURL=network.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"network.d.ts","sourceRoot":"","sources":["../../../src/analyzers/network.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAIvD;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAuBlF;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CA2DzE;AAED;;GAEG;AACH,wBAAsB,yBAAyB,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAsH1F"}
@@ -0,0 +1,203 @@
1
+ import axios from 'axios';
2
+ import pLimit from 'p-limit';
3
+ const limit = pLimit(10); // Increased concurrency for network checks
4
+ /**
5
+ * Main entry point for network audit.
6
+ * Checks vulnerabilities for all packages.
7
+ * Checks reputation for a subset (or all if count is low) to avoid rate limiting.
8
+ */
9
+ export async function auditDependencies(packages) {
10
+ const findings = [];
11
+ // 1. Vulnerabilities (Batch API - Fast)
12
+ try {
13
+ const vulnFindings = await checkVulnerabilitiesBatch(packages);
14
+ findings.push(...vulnFindings);
15
+ }
16
+ catch (e) {
17
+ console.error('Vulnerability check failed:', e);
18
+ }
19
+ // 2. Reputation (Per-package API - Slow)
20
+ // Only check reputation if < 200 packages to avoid long wait times
21
+ if (packages.length < 200) {
22
+ const reputationPromises = packages.map(p => checkReputation(p.name));
23
+ const repResults = await Promise.all(reputationPromises);
24
+ repResults.forEach(r => findings.push(...r));
25
+ }
26
+ else {
27
+ // For large trees, maybe only check random sample?
28
+ // Or just skip to be safe.
29
+ }
30
+ return findings;
31
+ }
32
+ /**
33
+ * Checks the npm registry for package reputation (downloads, age).
34
+ */
35
+ export async function checkReputation(pkgName) {
36
+ return limit(async () => {
37
+ try {
38
+ // 1. Get Metadata (Time, Maintainers)
39
+ const regUrl = `https://registry.npmjs.org/${pkgName}`;
40
+ const { data: meta } = await axios.get(regUrl, { timeout: 3000 });
41
+ const findings = [];
42
+ const now = new Date();
43
+ const created = new Date(meta.time.created);
44
+ const ageDays = (now.getTime() - created.getTime()) / (1000 * 60 * 60 * 24);
45
+ if (ageDays < 14) {
46
+ findings.push({
47
+ type: 'Reputation',
48
+ name: pkgName,
49
+ file: 'package.json',
50
+ severity: 'high',
51
+ description: `Package is brand new (created ${Math.round(ageDays)} days ago).`
52
+ });
53
+ }
54
+ // 2. Get Downloads (Popularity)
55
+ try {
56
+ const dlUrl = `https://api.npmjs.org/downloads/point/last-week/${pkgName}`;
57
+ const { data: dl } = await axios.get(dlUrl, { timeout: 3000 });
58
+ if (dl.downloads < 50) {
59
+ findings.push({
60
+ type: 'Reputation',
61
+ name: pkgName,
62
+ file: 'package.json',
63
+ severity: 'medium',
64
+ description: `Extremely low downloads (${dl.downloads}/week). Potential typosquat or abandoned.`
65
+ });
66
+ }
67
+ }
68
+ catch (e) {
69
+ // Download stats might be private/unavailable
70
+ }
71
+ return findings;
72
+ }
73
+ catch (error) {
74
+ if (error.response && error.response.status === 404) {
75
+ const isScoped = pkgName.startsWith('@');
76
+ return [{
77
+ type: 'Reputation',
78
+ name: pkgName,
79
+ file: 'package.json',
80
+ severity: isScoped ? 'low' : 'critical',
81
+ description: isScoped
82
+ ? 'Scoped package not found in public registry (Likely Private).'
83
+ : 'Unscoped package not found in registry (Possible Malware/Typosquat).'
84
+ }];
85
+ }
86
+ return [];
87
+ }
88
+ });
89
+ }
90
+ /**
91
+ * Checks for known vulnerabilities using OSV API (Batch Mode).
92
+ */
93
+ export async function checkVulnerabilitiesBatch(packages) {
94
+ if (packages.length === 0)
95
+ return [];
96
+ const chunkSize = 500;
97
+ const chunks = [];
98
+ for (let i = 0; i < packages.length; i += chunkSize) {
99
+ chunks.push(packages.slice(i, i + chunkSize));
100
+ }
101
+ const allVulns = [];
102
+ for (const chunk of chunks) {
103
+ try {
104
+ const payload = {
105
+ queries: chunk.map(p => ({
106
+ package: { name: p.name, ecosystem: 'npm' },
107
+ version: p.version
108
+ }))
109
+ };
110
+ const { data } = await axios.post('https://api.osv.dev/v1/querybatch', payload, { timeout: 10000 });
111
+ const vulnIds = new Set();
112
+ data.results.forEach((res) => {
113
+ if (res.vulns) {
114
+ res.vulns.forEach((v) => vulnIds.add(v.id));
115
+ }
116
+ });
117
+ const detailsMap = new Map();
118
+ const detailPromises = Array.from(vulnIds).map(id => limit(async () => {
119
+ try {
120
+ const { data: detail } = await axios.get(`https://api.osv.dev/v1/vulns/${id}`, { timeout: 5000 });
121
+ detailsMap.set(id, detail);
122
+ }
123
+ catch (e) { }
124
+ }));
125
+ await Promise.all(detailPromises);
126
+ data.results.forEach((res, idx) => {
127
+ if (res.vulns && res.vulns.length > 0) {
128
+ const pkg = chunk[idx];
129
+ if (!pkg)
130
+ return;
131
+ res.vulns.forEach((basicV) => {
132
+ const v = detailsMap.get(basicV.id) || basicV;
133
+ let fixedIn = 'Unknown';
134
+ if (v.affected) {
135
+ for (const affected of v.affected) {
136
+ if (affected.ranges) {
137
+ for (const range of affected.ranges) {
138
+ if (range.events) {
139
+ for (const event of range.events) {
140
+ if (event.fixed) {
141
+ if (fixedIn === 'Unknown' || event.fixed > fixedIn) {
142
+ fixedIn = event.fixed;
143
+ }
144
+ }
145
+ }
146
+ }
147
+ }
148
+ }
149
+ }
150
+ }
151
+ let severity = 'high';
152
+ if (v.database_specific && v.database_specific.severity) {
153
+ severity = v.database_specific.severity.toLowerCase();
154
+ }
155
+ else if (v.severity && v.severity.length > 0) {
156
+ severity = 'high';
157
+ }
158
+ else {
159
+ const text = JSON.stringify(v).toLowerCase();
160
+ if (text.includes('critical'))
161
+ severity = 'critical';
162
+ else if (text.includes('high'))
163
+ severity = 'high';
164
+ else if (text.includes('medium'))
165
+ severity = 'medium';
166
+ else
167
+ severity = 'low';
168
+ }
169
+ const externalRefs = [];
170
+ if (v.aliases) {
171
+ v.aliases.forEach((alias) => {
172
+ if (alias.startsWith('CVE-')) {
173
+ externalRefs.push(`Snyk: https://security.snyk.io/vuln?search=${alias}`);
174
+ externalRefs.push(`ExploitDB: https://www.exploit-db.com/search?cve=${alias.replace('CVE-', '')}`);
175
+ }
176
+ });
177
+ }
178
+ const osvUrl = `https://osv.dev/vulnerability/${v.id}`;
179
+ const summary = v.summary || v.details?.split('\n')[0] || 'Vulnerability detected';
180
+ allVulns.push({
181
+ type: 'Vulnerability',
182
+ name: pkg.name,
183
+ version: pkg.version,
184
+ severity: severity,
185
+ file: 'package-lock.json',
186
+ id: v.id,
187
+ summary: summary,
188
+ url: osvUrl,
189
+ fixedIn: fixedIn,
190
+ description: summary,
191
+ references: externalRefs
192
+ });
193
+ });
194
+ }
195
+ });
196
+ }
197
+ catch (e) {
198
+ console.error(e);
199
+ }
200
+ }
201
+ return allVulns;
202
+ }
203
+ //# sourceMappingURL=network.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"network.js","sourceRoot":"","sources":["../../../src/analyzers/network.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ export interface Finding {
2
+ type: string;
3
+ name?: string;
4
+ file: string;
5
+ line?: number;
6
+ severity: 'critical' | 'high' | 'medium' | 'low';
7
+ content?: string;
8
+ description: string;
9
+ version?: string;
10
+ id?: string;
11
+ summary?: string;
12
+ url?: string;
13
+ fixedIn?: string;
14
+ references?: string[];
15
+ }
16
+ export declare function analyzeStream(filePath: string): Promise<Finding[]>;
17
+ export declare function analyzeContent(content: string, file: string): Finding[];
18
+ //# sourceMappingURL=static-analysis.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"static-analysis.d.ts","sourceRoot":"","sources":["../../../src/analyzers/static-analysis.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACjD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CA4CxE;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE,CA+MvE"}