devcompass 2.7.0 → 2.7.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devcompass",
3
- "version": "2.7.0",
3
+ "version": "2.7.1",
4
4
  "description": "Dependency health checker with ecosystem intelligence, real-time GitHub issue tracking for 500+ popular npm packages, parallel processing, supply chain security analysis, and advanced license risk detection.",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -76,4 +76,4 @@
76
76
  "url": "https://github.com/AjayBThorat-20/devcompass/issues"
77
77
  },
78
78
  "homepage": "https://github.com/AjayBThorat-20/devcompass#readme"
79
- }
79
+ }
@@ -54,45 +54,51 @@ function levenshteinDistance(str1, str2) {
54
54
  /**
55
55
  * Detect typosquatting attempts
56
56
  */
57
- function detectTyposquatting(packageName, database) {
57
+ function detectTyposquatting(packageName, packageVersion, maliciousDb) {
58
58
  const warnings = [];
59
59
 
60
+ // Whitelist of legitimate popular packages that might have similar names
61
+ // These should NEVER be flagged as typosquatting
62
+ const LEGITIMATE_PACKAGES = [
63
+ 'chalk', 'chai', 'ora', 'yargs', 'meow', 'execa', 'globby', 'del', 'make-dir',
64
+ 'p-map', 'p-limit', 'p-queue', 'got', 'ky', 'node-fetch', 'cross-fetch',
65
+ 'uuid', 'nanoid', 'cuid', 'luxon', 'date-fns', 'ms', 'bytes', 'filesize',
66
+ 'fast-glob', 'chokidar', 'picomatch', 'micromatch', 'anymatch',
67
+ 'semver', 'commander', 'yargs', 'inquirer', 'prompts', 'enquirer',
68
+ 'debug', 'pino', 'winston', 'bunyan', 'signale'
69
+ ];
70
+
71
+ // Skip whitelist packages
72
+ if (LEGITIMATE_PACKAGES.includes(packageName)) {
73
+ return warnings;
74
+ }
75
+
60
76
  // Check against known typosquat patterns
61
- for (const [official, typos] of Object.entries(database.typosquat_patterns)) {
62
- if (typos.includes(packageName.toLowerCase())) {
77
+ // typosquat_patterns is an object: { "express": ["epress", "expres"], ... }
78
+ const patterns = maliciousDb.typosquat_patterns || {};
79
+
80
+ for (const officialName of Object.keys(patterns)) {
81
+ // Skip if the official package is also whitelisted (both are legitimate)
82
+ // This prevents false positives like "chalk" vs "chai"
83
+ if (LEGITIMATE_PACKAGES.includes(officialName)) {
84
+ continue;
85
+ }
86
+
87
+ const distance = levenshteinDistance(packageName, officialName);
88
+
89
+ // Flag if 1-2 character difference (typosquatting likely)
90
+ if (distance > 0 && distance <= 2 && packageName !== officialName) {
63
91
  warnings.push({
64
- package: packageName,
92
+ package: `${packageName}@${packageVersion}`,
65
93
  type: 'typosquatting',
66
- severity: 'high',
67
- official: official,
68
- message: `Potential typosquatting: "${packageName}" is similar to official package "${official}"`,
69
- recommendation: `Remove ${packageName} and install ${official} instead`
94
+ severity: distance === 1 ? 'high' : 'medium',
95
+ message: `Similar to: ${officialName} (official package)`,
96
+ recommendation: `Verify if you meant to install ${officialName}`,
97
+ official: officialName
70
98
  });
71
99
  }
72
100
  }
73
101
 
74
- // Check Levenshtein distance against popular packages
75
- const popularPackages = Object.keys(database.typosquat_patterns);
76
- for (const popular of popularPackages) {
77
- const distance = levenshteinDistance(packageName.toLowerCase(), popular.toLowerCase());
78
-
79
- // If distance is 1-2 characters and not already flagged
80
- if (distance > 0 && distance <= 2 && packageName !== popular) {
81
- const alreadyFlagged = warnings.some(w => w.package === packageName);
82
-
83
- if (!alreadyFlagged) {
84
- warnings.push({
85
- package: packageName,
86
- type: 'typosquatting_suspected',
87
- severity: 'medium',
88
- official: popular,
89
- message: `Possible typosquatting: "${packageName}" is very similar to "${popular}"`,
90
- recommendation: `Verify if you meant to install ${popular}`
91
- });
92
- }
93
- }
94
- }
95
-
96
102
  return warnings;
97
103
  }
98
104
 
@@ -181,7 +187,7 @@ async function analyzeSupplyChain(projectPath, dependencies) {
181
187
  }
182
188
 
183
189
  // 2. Detect typosquatting
184
- const typosquatWarnings = detectTyposquatting(packageName, database);
190
+ const typosquatWarnings = detectTyposquatting(packageName, version, database);
185
191
  warnings.push(...typosquatWarnings);
186
192
  }
187
193