code-auditor-mcp 1.20.0 → 2.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.
- package/dist/adapters/GoAdapter.d.ts +53 -0
- package/dist/adapters/GoAdapter.d.ts.map +1 -0
- package/dist/adapters/GoAdapter.js +602 -0
- package/dist/adapters/GoAdapter.js.map +1 -0
- package/dist/adapters/GoConfig.d.ts +35 -0
- package/dist/adapters/GoConfig.d.ts.map +1 -0
- package/dist/adapters/GoConfig.js +155 -0
- package/dist/adapters/GoConfig.js.map +1 -0
- package/dist/adapters/LanguageAdapter.d.ts +135 -0
- package/dist/adapters/LanguageAdapter.d.ts.map +1 -0
- package/dist/adapters/LanguageAdapter.js +47 -0
- package/dist/adapters/LanguageAdapter.js.map +1 -0
- package/dist/adapters/TypeScriptAdapter.d.ts +43 -0
- package/dist/adapters/TypeScriptAdapter.d.ts.map +1 -0
- package/dist/adapters/TypeScriptAdapter.js +386 -0
- package/dist/adapters/TypeScriptAdapter.js.map +1 -0
- package/dist/adapters/UniversalAnalyzer.d.ts +42 -0
- package/dist/adapters/UniversalAnalyzer.d.ts.map +1 -0
- package/dist/adapters/UniversalAnalyzer.js +103 -0
- package/dist/adapters/UniversalAnalyzer.js.map +1 -0
- package/dist/adapters/UniversalSOLIDAnalyzer.d.ts +48 -0
- package/dist/adapters/UniversalSOLIDAnalyzer.d.ts.map +1 -0
- package/dist/adapters/UniversalSOLIDAnalyzer.js +178 -0
- package/dist/adapters/UniversalSOLIDAnalyzer.js.map +1 -0
- package/dist/adapters/solidAnalyzerCompat.d.ts +21 -0
- package/dist/adapters/solidAnalyzerCompat.d.ts.map +1 -0
- package/dist/adapters/solidAnalyzerCompat.js +78 -0
- package/dist/adapters/solidAnalyzerCompat.js.map +1 -0
- package/dist/analyzers/cross-language/APIContractAnalyzer.d.ts +103 -0
- package/dist/analyzers/cross-language/APIContractAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/cross-language/APIContractAnalyzer.js +425 -0
- package/dist/analyzers/cross-language/APIContractAnalyzer.js.map +1 -0
- package/dist/analyzers/cross-language/CrossLanguageSOLIDAnalyzer.d.ts +117 -0
- package/dist/analyzers/cross-language/CrossLanguageSOLIDAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/cross-language/CrossLanguageSOLIDAnalyzer.js +618 -0
- package/dist/analyzers/cross-language/CrossLanguageSOLIDAnalyzer.js.map +1 -0
- package/dist/analyzers/cross-language/DependencyGraphBuilder.d.ts +129 -0
- package/dist/analyzers/cross-language/DependencyGraphBuilder.d.ts.map +1 -0
- package/dist/analyzers/cross-language/DependencyGraphBuilder.js +473 -0
- package/dist/analyzers/cross-language/DependencyGraphBuilder.js.map +1 -0
- package/dist/analyzers/cross-language/SchemaValidator.d.ts +126 -0
- package/dist/analyzers/cross-language/SchemaValidator.d.ts.map +1 -0
- package/dist/analyzers/cross-language/SchemaValidator.js +522 -0
- package/dist/analyzers/cross-language/SchemaValidator.js.map +1 -0
- package/dist/analyzers/dataAccessAnalyzerCompat.d.ts +20 -0
- package/dist/analyzers/dataAccessAnalyzerCompat.d.ts.map +1 -0
- package/dist/analyzers/dataAccessAnalyzerCompat.js +59 -0
- package/dist/analyzers/dataAccessAnalyzerCompat.js.map +1 -0
- package/dist/analyzers/documentationAnalyzerCompat.d.ts +20 -0
- package/dist/analyzers/documentationAnalyzerCompat.d.ts.map +1 -0
- package/dist/analyzers/documentationAnalyzerCompat.js +52 -0
- package/dist/analyzers/documentationAnalyzerCompat.js.map +1 -0
- package/dist/analyzers/dryAnalyzerCompat.d.ts +20 -0
- package/dist/analyzers/dryAnalyzerCompat.d.ts.map +1 -0
- package/dist/analyzers/dryAnalyzerCompat.js +44 -0
- package/dist/analyzers/dryAnalyzerCompat.js.map +1 -0
- package/dist/analyzers/schemaAnalyzer.d.ts +21 -0
- package/dist/analyzers/schemaAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/schemaAnalyzer.js +405 -0
- package/dist/analyzers/schemaAnalyzer.js.map +1 -0
- package/dist/analyzers/schemaAnalyzerCompat.d.ts +20 -0
- package/dist/analyzers/schemaAnalyzerCompat.d.ts.map +1 -0
- package/dist/analyzers/schemaAnalyzerCompat.js +69 -0
- package/dist/analyzers/schemaAnalyzerCompat.js.map +1 -0
- package/dist/analyzers/solidAnalyzerCompat.d.ts +20 -0
- package/dist/analyzers/solidAnalyzerCompat.d.ts.map +1 -0
- package/dist/analyzers/solidAnalyzerCompat.js +78 -0
- package/dist/analyzers/solidAnalyzerCompat.js.map +1 -0
- package/dist/analyzers/universal/UniversalDRYAnalyzer.d.ts +71 -0
- package/dist/analyzers/universal/UniversalDRYAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/universal/UniversalDRYAnalyzer.js +276 -0
- package/dist/analyzers/universal/UniversalDRYAnalyzer.js.map +1 -0
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.d.ts +82 -0
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.js +489 -0
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.js.map +1 -0
- package/dist/analyzers/universal/UniversalDocumentationAnalyzer.d.ts +48 -0
- package/dist/analyzers/universal/UniversalDocumentationAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/universal/UniversalDocumentationAnalyzer.js +175 -0
- package/dist/analyzers/universal/UniversalDocumentationAnalyzer.js.map +1 -0
- package/dist/analyzers/universal/UniversalSOLIDAnalyzer.d.ts +64 -0
- package/dist/analyzers/universal/UniversalSOLIDAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/universal/UniversalSOLIDAnalyzer.js +286 -0
- package/dist/analyzers/universal/UniversalSOLIDAnalyzer.js.map +1 -0
- package/dist/analyzers/universal/UniversalSchemaAnalyzer.d.ts +119 -0
- package/dist/analyzers/universal/UniversalSchemaAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/universal/UniversalSchemaAnalyzer.js +812 -0
- package/dist/analyzers/universal/UniversalSchemaAnalyzer.js.map +1 -0
- package/dist/auditRunner.d.ts.map +1 -1
- package/dist/auditRunner.js +23 -7
- package/dist/auditRunner.js.map +1 -1
- package/dist/codeIndexDB-enhanced.d.ts +80 -0
- package/dist/codeIndexDB-enhanced.d.ts.map +1 -0
- package/dist/codeIndexDB-enhanced.js +488 -0
- package/dist/codeIndexDB-enhanced.js.map +1 -0
- package/dist/codeIndexDb.d.ts +70 -1
- package/dist/codeIndexDb.d.ts.map +1 -1
- package/dist/codeIndexDb.js +199 -2
- package/dist/codeIndexDb.js.map +1 -1
- package/dist/config/defaults.js +1 -1
- package/dist/config/defaults.js.map +1 -1
- package/dist/languages/LanguageOrchestrator.d.ts +181 -0
- package/dist/languages/LanguageOrchestrator.d.ts.map +1 -0
- package/dist/languages/LanguageOrchestrator.js +365 -0
- package/dist/languages/LanguageOrchestrator.js.map +1 -0
- package/dist/languages/LanguageRegistry.d.ts +43 -0
- package/dist/languages/LanguageRegistry.d.ts.map +1 -0
- package/dist/languages/LanguageRegistry.js +86 -0
- package/dist/languages/LanguageRegistry.js.map +1 -0
- package/dist/languages/RuntimeManager.d.ts +181 -0
- package/dist/languages/RuntimeManager.d.ts.map +1 -0
- package/dist/languages/RuntimeManager.js +841 -0
- package/dist/languages/RuntimeManager.js.map +1 -0
- package/dist/languages/UniversalAnalyzer.d.ts +37 -0
- package/dist/languages/UniversalAnalyzer.d.ts.map +1 -0
- package/dist/languages/UniversalAnalyzer.js +101 -0
- package/dist/languages/UniversalAnalyzer.js.map +1 -0
- package/dist/languages/go/GoAdapter.d.ts +57 -0
- package/dist/languages/go/GoAdapter.d.ts.map +1 -0
- package/dist/languages/go/GoAdapter.js +360 -0
- package/dist/languages/go/GoAdapter.js.map +1 -0
- package/dist/languages/index.d.ts +13 -0
- package/dist/languages/index.d.ts.map +1 -0
- package/dist/languages/index.js +23 -0
- package/dist/languages/index.js.map +1 -0
- package/dist/languages/types.d.ts +182 -0
- package/dist/languages/types.d.ts.map +1 -0
- package/dist/languages/types.js +5 -0
- package/dist/languages/types.js.map +1 -0
- package/dist/languages/typescript/TypeScriptAdapter.d.ts +108 -0
- package/dist/languages/typescript/TypeScriptAdapter.d.ts.map +1 -0
- package/dist/languages/typescript/TypeScriptAdapter.js +567 -0
- package/dist/languages/typescript/TypeScriptAdapter.js.map +1 -0
- package/dist/languages/typescript/test-extraction.d.ts +2 -0
- package/dist/languages/typescript/test-extraction.d.ts.map +1 -0
- package/dist/languages/typescript/test-extraction.js +36 -0
- package/dist/languages/typescript/test-extraction.js.map +1 -0
- package/dist/mcp-hybrid.d.ts +10 -0
- package/dist/mcp-hybrid.d.ts.map +1 -0
- package/dist/mcp-hybrid.js +41 -0
- package/dist/mcp-hybrid.js.map +1 -0
- package/dist/mcp-index.d.ts +11 -0
- package/dist/mcp-index.d.ts.map +1 -0
- package/dist/mcp-index.js +101 -0
- package/dist/mcp-index.js.map +1 -0
- package/dist/mcp-tools/workflowGuide.d.ts.map +1 -1
- package/dist/mcp-tools/workflowGuide.js +67 -10
- package/dist/mcp-tools/workflowGuide.js.map +1 -1
- package/dist/mcp-tools-shared.d.ts +49 -0
- package/dist/mcp-tools-shared.d.ts.map +1 -0
- package/dist/mcp-tools-shared.js +1282 -0
- package/dist/mcp-tools-shared.js.map +1 -0
- package/dist/mcp-ui-server.d.ts +27 -0
- package/dist/mcp-ui-server.d.ts.map +1 -0
- package/dist/mcp-ui-server.js +484 -0
- package/dist/mcp-ui-server.js.map +1 -0
- package/dist/mcp-ui-simple.d.ts +27 -0
- package/dist/mcp-ui-simple.d.ts.map +1 -0
- package/dist/mcp-ui-simple.js +425 -0
- package/dist/mcp-ui-simple.js.map +1 -0
- package/dist/mcp.js +7 -4
- package/dist/mcp.js.map +1 -1
- package/dist/services/SchemaParser.d.ts +89 -0
- package/dist/services/SchemaParser.d.ts.map +1 -0
- package/dist/services/SchemaParser.js +434 -0
- package/dist/services/SchemaParser.js.map +1 -0
- package/dist/types/crossLanguage.d.ts +267 -0
- package/dist/types/crossLanguage.d.ts.map +1 -0
- package/dist/types/crossLanguage.js +6 -0
- package/dist/types/crossLanguage.js.map +1 -0
- package/dist/types.d.ts +128 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/fileDiscovery.d.ts +6 -0
- package/dist/utils/fileDiscovery.d.ts.map +1 -1
- package/dist/utils/fileDiscovery.js +12 -1
- package/dist/utils/fileDiscovery.js.map +1 -1
- package/examples/schema-example.json +364 -0
- package/examples/schema-example.yaml +137 -0
- package/package.json +10 -3
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Universal Data Access Analyzer
|
|
3
|
+
* Works across multiple programming languages using the adapter pattern
|
|
4
|
+
* Analyzes database access patterns and data layer interactions
|
|
5
|
+
*/
|
|
6
|
+
import { UniversalAnalyzer } from '../../languages/UniversalAnalyzer.js';
|
|
7
|
+
export const DEFAULT_DATA_ACCESS_CONFIG = {
|
|
8
|
+
checkOrgFilters: true,
|
|
9
|
+
checkSQLInjection: true,
|
|
10
|
+
databases: {
|
|
11
|
+
'primary': {
|
|
12
|
+
name: 'Primary Database',
|
|
13
|
+
importPatterns: ['/database/', '/db/', './db', './schema', 'drizzle', 'prisma', 'typeorm', 'knex', 'sequelize'],
|
|
14
|
+
queryPatterns: ['select', 'insert', 'update', 'delete', 'query', 'execute'],
|
|
15
|
+
ormPatterns: ['from', 'where', 'join', 'orderBy', 'groupBy']
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
organizationPatterns: [
|
|
19
|
+
'organizationId',
|
|
20
|
+
'organization_id',
|
|
21
|
+
'orgId',
|
|
22
|
+
'org_id',
|
|
23
|
+
'tenantId',
|
|
24
|
+
'tenant_id',
|
|
25
|
+
'companyId',
|
|
26
|
+
'company_id'
|
|
27
|
+
],
|
|
28
|
+
tablePatterns: {
|
|
29
|
+
orm: [
|
|
30
|
+
/from\s*\(\s*["'`]?(\w+)["'`]?\s*\)/i,
|
|
31
|
+
/table\s*[:=]\s*["'`]?(\w+)["'`]?/i,
|
|
32
|
+
/\.from\s*\(\s*(\w+)\s*\)/i, // Handle .from(users) where users is a variable
|
|
33
|
+
/join\s*\(\s*(\w+)\s*,/i, // Handle joins
|
|
34
|
+
/leftJoin\s*\(\s*(\w+)\s*,/i,
|
|
35
|
+
/rightJoin\s*\(\s*(\w+)\s*,/i,
|
|
36
|
+
/innerJoin\s*\(\s*(\w+)\s*,/i
|
|
37
|
+
],
|
|
38
|
+
sql: [/FROM\s+["'`]?(\w+)["'`]?/i, /JOIN\s+["'`]?(\w+)["'`]?/i, /UPDATE\s+["'`]?(\w+)["'`]?/i],
|
|
39
|
+
queryBuilder: [/\.from\s*\(\s*["'`]?(\w+)["'`]?\s*\)/i]
|
|
40
|
+
},
|
|
41
|
+
performanceThresholds: {
|
|
42
|
+
complexQueryCount: 3,
|
|
43
|
+
unfilteredQueryCount: 3,
|
|
44
|
+
joinedTableCount: 4
|
|
45
|
+
},
|
|
46
|
+
securityPatterns: {
|
|
47
|
+
sqlInjectionRisks: ['${', 'concat', 'string interpolation'],
|
|
48
|
+
parameterizedQueries: ['?', ':param', '$1', 'prepared', 'parameterized']
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
export class UniversalDataAccessAnalyzer extends UniversalAnalyzer {
|
|
52
|
+
name = 'data-access';
|
|
53
|
+
description = 'Analyzes database access patterns and data layer interactions';
|
|
54
|
+
category = 'security';
|
|
55
|
+
async analyzeAST(ast, adapter, config, sourceCode) {
|
|
56
|
+
const violations = [];
|
|
57
|
+
const finalConfig = { ...DEFAULT_DATA_ACCESS_CONFIG, ...config };
|
|
58
|
+
console.log('[DEBUG] Data access config merge:', {
|
|
59
|
+
defaultPatterns: DEFAULT_DATA_ACCESS_CONFIG.organizationPatterns,
|
|
60
|
+
inputConfig: config,
|
|
61
|
+
finalPatterns: finalConfig.organizationPatterns
|
|
62
|
+
});
|
|
63
|
+
// Check imports for database libraries
|
|
64
|
+
const imports = adapter.extractImports(ast);
|
|
65
|
+
const dbImports = this.mapDatabaseImports(imports, finalConfig);
|
|
66
|
+
// Find database calls
|
|
67
|
+
const calls = this.extractDatabaseCalls(ast, adapter, sourceCode, dbImports, finalConfig);
|
|
68
|
+
// Analyze each call
|
|
69
|
+
for (const call of calls) {
|
|
70
|
+
const analysis = this.analyzeQuery(call, sourceCode, finalConfig);
|
|
71
|
+
// Check for violations
|
|
72
|
+
violations.push(...this.checkViolations(call, analysis, ast.filePath, finalConfig));
|
|
73
|
+
}
|
|
74
|
+
// Check for general data access patterns
|
|
75
|
+
violations.push(...this.checkGeneralPatterns(ast, adapter, sourceCode, finalConfig));
|
|
76
|
+
return violations;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Map imports to database types
|
|
80
|
+
*/
|
|
81
|
+
mapDatabaseImports(imports, config) {
|
|
82
|
+
const dbImports = new Map();
|
|
83
|
+
Object.entries(config.databases || {}).forEach(([dbType, dbConfig]) => {
|
|
84
|
+
const hasImports = imports.some(imp => dbConfig.importPatterns.some(pattern => imp.source.includes(pattern)));
|
|
85
|
+
dbImports.set(dbType, {
|
|
86
|
+
hasImports,
|
|
87
|
+
patterns: [...dbConfig.queryPatterns, ...(dbConfig.ormPatterns || [])]
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
return dbImports;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Extract database calls from AST
|
|
94
|
+
*/
|
|
95
|
+
extractDatabaseCalls(ast, adapter, sourceCode, dbImports, config) {
|
|
96
|
+
const calls = [];
|
|
97
|
+
// Find all relevant nodes
|
|
98
|
+
const allNodes = adapter.findNodes(ast, {
|
|
99
|
+
custom: (node) => {
|
|
100
|
+
const nodeText = adapter.getNodeText(node, sourceCode);
|
|
101
|
+
// Check if it's a function call that might be database-related
|
|
102
|
+
if (this.isFunctionCall(node, adapter)) {
|
|
103
|
+
// Check for ORM patterns or database method calls
|
|
104
|
+
const dbPatterns = ['select', 'insert', 'update', 'delete', 'from', 'where', 'execute', 'query', 'find', 'aggregate', 'count', 'distinct'];
|
|
105
|
+
const hasDbPattern = dbPatterns.some(pattern => nodeText.toLowerCase().includes(pattern));
|
|
106
|
+
if (hasDbPattern) {
|
|
107
|
+
// Ensure we get the full method call including arguments
|
|
108
|
+
// For method calls like db.users.find(...), we want the entire expression
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// Check if it's a template literal with SQL
|
|
113
|
+
if (this.isTemplateLiteral(node, adapter)) {
|
|
114
|
+
return this.containsSQLKeywords(nodeText);
|
|
115
|
+
}
|
|
116
|
+
// Check if it's a variable declaration with SQL (but not if it contains a template literal)
|
|
117
|
+
if (this.isVariableAssignment(node, adapter)) {
|
|
118
|
+
if (!this.containsSQLKeywords(nodeText))
|
|
119
|
+
return false;
|
|
120
|
+
// Skip parent nodes if they contain template literals we'll analyze separately
|
|
121
|
+
const children = adapter.getChildren(node);
|
|
122
|
+
const hasRelevantChild = children.some(child => this.isTemplateLiteral(child, adapter) &&
|
|
123
|
+
this.containsSQLKeywords(adapter.getNodeText(child, sourceCode)));
|
|
124
|
+
return !hasRelevantChild;
|
|
125
|
+
}
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
// Deduplicate by line, preferring the most specific node
|
|
130
|
+
const nodesByLine = new Map();
|
|
131
|
+
allNodes.forEach(node => {
|
|
132
|
+
const line = node.location.start.line;
|
|
133
|
+
if (!nodesByLine.has(line)) {
|
|
134
|
+
nodesByLine.set(line, []);
|
|
135
|
+
}
|
|
136
|
+
nodesByLine.get(line).push(node);
|
|
137
|
+
});
|
|
138
|
+
// For each line, pick the most specific node
|
|
139
|
+
const uniqueNodes = [];
|
|
140
|
+
nodesByLine.forEach(nodes => {
|
|
141
|
+
if (nodes.length === 1) {
|
|
142
|
+
uniqueNodes.push(nodes[0]);
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
// Prefer template literals over variable declarations
|
|
146
|
+
const templateLiteral = nodes.find(n => this.isTemplateLiteral(n, adapter));
|
|
147
|
+
if (templateLiteral) {
|
|
148
|
+
uniqueNodes.push(templateLiteral);
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
// Otherwise take the first one
|
|
152
|
+
uniqueNodes.push(nodes[0]);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
for (const node of uniqueNodes) {
|
|
157
|
+
const nodeText = adapter.getNodeText(node, sourceCode);
|
|
158
|
+
// Skip if the node text is too short or doesn't contain meaningful content
|
|
159
|
+
if (!nodeText || nodeText.trim().length < 10)
|
|
160
|
+
continue;
|
|
161
|
+
// Determine if this is a database-related call
|
|
162
|
+
const isSqlQuery = this.containsSQLKeywords(nodeText);
|
|
163
|
+
const isOrmCall = this.isOrmPattern(nodeText);
|
|
164
|
+
if (isSqlQuery || isOrmCall) {
|
|
165
|
+
const tables = this.extractTables(nodeText, config);
|
|
166
|
+
const hasOrgFilter = this.hasOrganizationFilter(nodeText, config);
|
|
167
|
+
// Debug: Log the analysis
|
|
168
|
+
console.log('[DEBUG] Database call analysis:', {
|
|
169
|
+
line: node.location.start.line,
|
|
170
|
+
nodeText: nodeText.substring(0, 100),
|
|
171
|
+
tables,
|
|
172
|
+
hasOrgFilter,
|
|
173
|
+
patterns: config.organizationPatterns || []
|
|
174
|
+
});
|
|
175
|
+
const security = this.checkQuerySecurity(nodeText, config);
|
|
176
|
+
// Debug: Log extracted tables
|
|
177
|
+
if (tables.length === 0 && isOrmCall) {
|
|
178
|
+
console.error('[DataAccess Debug] No tables extracted from ORM call:', {
|
|
179
|
+
line: node.location.start.line,
|
|
180
|
+
nodeText: nodeText.substring(0, 100)
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
// Determine the type based on imports or patterns
|
|
184
|
+
let callType = 'unknown';
|
|
185
|
+
if (isSqlQuery) {
|
|
186
|
+
callType = 'sql';
|
|
187
|
+
}
|
|
188
|
+
else if (isOrmCall) {
|
|
189
|
+
// Check which ORM based on imports
|
|
190
|
+
for (const [dbType, importInfo] of dbImports) {
|
|
191
|
+
if (importInfo.hasImports) {
|
|
192
|
+
callType = dbType;
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
calls.push({
|
|
198
|
+
type: callType,
|
|
199
|
+
method: this.extractMethodName(node, adapter, sourceCode),
|
|
200
|
+
file: ast.filePath,
|
|
201
|
+
line: node.location.start.line,
|
|
202
|
+
column: node.location.start.column,
|
|
203
|
+
tables,
|
|
204
|
+
hasOrganizationFilter: hasOrgFilter,
|
|
205
|
+
hasParameterizedQuery: security.parameterized,
|
|
206
|
+
hasSqlInjectionRisk: security.injectionRisk
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return calls;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Analyze a database query
|
|
214
|
+
*/
|
|
215
|
+
analyzeQuery(call, sourceCode, config) {
|
|
216
|
+
const hasJoins = call.tables.length > 1;
|
|
217
|
+
const hasSubquery = sourceCode.includes('SELECT') && sourceCode.includes('FROM') &&
|
|
218
|
+
sourceCode.lastIndexOf('SELECT') !== sourceCode.indexOf('SELECT');
|
|
219
|
+
let complexity = 'simple';
|
|
220
|
+
if (hasSubquery || call.tables.length > 3) {
|
|
221
|
+
complexity = 'complex';
|
|
222
|
+
}
|
|
223
|
+
else if (hasJoins || call.tables.length > 1) {
|
|
224
|
+
complexity = 'moderate';
|
|
225
|
+
}
|
|
226
|
+
let performanceRisk = 'low';
|
|
227
|
+
if (call.tables.length > (config.performanceThresholds?.joinedTableCount || 4)) {
|
|
228
|
+
performanceRisk = 'high';
|
|
229
|
+
}
|
|
230
|
+
else if (!call.hasOrganizationFilter && call.tables.length > 0) {
|
|
231
|
+
performanceRisk = 'medium';
|
|
232
|
+
}
|
|
233
|
+
return {
|
|
234
|
+
complexity,
|
|
235
|
+
tables: call.tables,
|
|
236
|
+
hasJoins,
|
|
237
|
+
hasSubquery,
|
|
238
|
+
hasOrganizationFilter: call.hasOrganizationFilter,
|
|
239
|
+
performanceRisk
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Check for violations in a database call
|
|
244
|
+
*/
|
|
245
|
+
checkViolations(call, analysis, filePath, config) {
|
|
246
|
+
const violations = [];
|
|
247
|
+
// Security: SQL Injection Risk
|
|
248
|
+
if (config.checkSQLInjection && call.hasSqlInjectionRisk) {
|
|
249
|
+
violations.push(this.createViolation(filePath, { line: call.line, column: call.column }, `Potential SQL injection risk in ${call.method}. Use parameterized queries.`, 'critical', 'sql-injection-risk'));
|
|
250
|
+
}
|
|
251
|
+
// Security: Missing Organization Filter
|
|
252
|
+
if (config.checkOrgFilters && !call.hasOrganizationFilter && call.tables.length > 0 && this.requiresOrgFilter(call.tables)) {
|
|
253
|
+
violations.push(this.createViolation(filePath, { line: call.line, column: call.column }, `Query on ${call.tables.join(', ')} missing organization/tenant filter`, 'warning', 'missing-org-filter'));
|
|
254
|
+
}
|
|
255
|
+
// Performance: Complex Query
|
|
256
|
+
if (analysis.performanceRisk === 'high') {
|
|
257
|
+
violations.push(this.createViolation(filePath, { line: call.line, column: call.column }, `Complex query with ${call.tables.length} tables may have performance issues`, 'warning', 'complex-query'));
|
|
258
|
+
}
|
|
259
|
+
// Performance: Unfiltered Query
|
|
260
|
+
if (!call.hasOrganizationFilter && analysis.performanceRisk === 'medium') {
|
|
261
|
+
violations.push(this.createViolation(filePath, { line: call.line, column: call.column }, `Unfiltered query on ${call.tables.join(', ')} may cause performance issues`, 'suggestion', 'unfiltered-query'));
|
|
262
|
+
}
|
|
263
|
+
return violations;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Check general data access patterns
|
|
267
|
+
*/
|
|
268
|
+
checkGeneralPatterns(ast, adapter, sourceCode, config) {
|
|
269
|
+
const violations = [];
|
|
270
|
+
// Check for hardcoded connection strings
|
|
271
|
+
const stringNodes = adapter.findNodes(ast, {
|
|
272
|
+
custom: (node) => this.isStringLiteral(node, adapter)
|
|
273
|
+
});
|
|
274
|
+
for (const node of stringNodes) {
|
|
275
|
+
const text = adapter.getNodeText(node, sourceCode);
|
|
276
|
+
if (this.isConnectionString(text)) {
|
|
277
|
+
violations.push(this.createViolation(ast.filePath, node.location.start, 'Hardcoded database connection string detected. Use environment variables.', 'critical', 'hardcoded-connection'));
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
// Check for direct SQL execution without ORM
|
|
281
|
+
const sqlPatterns = [/execute\s*\(\s*['"`]SELECT/i, /query\s*\(\s*['"`]SELECT/i];
|
|
282
|
+
for (const pattern of sqlPatterns) {
|
|
283
|
+
if (pattern.test(sourceCode)) {
|
|
284
|
+
violations.push(this.createViolation(ast.filePath, { line: 1, column: 1 }, 'Direct SQL execution detected. Consider using an ORM or query builder.', 'suggestion', 'direct-sql'));
|
|
285
|
+
break;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return violations;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Helper methods
|
|
292
|
+
*/
|
|
293
|
+
isFunctionCall(node, adapter) {
|
|
294
|
+
return node.type === 'CallExpression' ||
|
|
295
|
+
node.type === 'MethodCallExpression' ||
|
|
296
|
+
node.type === 'NewExpression';
|
|
297
|
+
}
|
|
298
|
+
isTemplateLiteral(node, adapter) {
|
|
299
|
+
return node.type === 'TemplateExpression' ||
|
|
300
|
+
node.type === 'NoSubstitutionTemplateLiteral';
|
|
301
|
+
}
|
|
302
|
+
isVariableAssignment(node, adapter) {
|
|
303
|
+
// Only get the actual variable declaration, not the statement
|
|
304
|
+
return node.type === 'VariableDeclaration' ||
|
|
305
|
+
node.type === 'BinaryExpression' && node.children?.some(child => adapter.getNodeText(child, '').includes('='));
|
|
306
|
+
}
|
|
307
|
+
containsSQLKeywords(text) {
|
|
308
|
+
const sqlKeywords = ['SELECT', 'INSERT', 'UPDATE', 'DELETE', 'FROM', 'WHERE', 'JOIN'];
|
|
309
|
+
const upperText = text.toUpperCase();
|
|
310
|
+
return sqlKeywords.some(keyword => upperText.includes(keyword));
|
|
311
|
+
}
|
|
312
|
+
isOrmPattern(text) {
|
|
313
|
+
// Common ORM method patterns
|
|
314
|
+
const ormPatterns = [
|
|
315
|
+
/\.find\s*\(/,
|
|
316
|
+
/\.findOne\s*\(/,
|
|
317
|
+
/\.findMany\s*\(/,
|
|
318
|
+
/\.findFirst\s*\(/,
|
|
319
|
+
/\.findUnique\s*\(/,
|
|
320
|
+
/\.select\s*\(/,
|
|
321
|
+
/\.insert\s*\(/,
|
|
322
|
+
/\.update\s*\(/,
|
|
323
|
+
/\.updateOne\s*\(/,
|
|
324
|
+
/\.updateMany\s*\(/,
|
|
325
|
+
/\.delete\s*\(/,
|
|
326
|
+
/\.deleteOne\s*\(/,
|
|
327
|
+
/\.deleteMany\s*\(/,
|
|
328
|
+
/\.from\s*\(/,
|
|
329
|
+
/\.where\s*\(/,
|
|
330
|
+
/\.join\s*\(/,
|
|
331
|
+
/\.leftJoin\s*\(/,
|
|
332
|
+
/\.rightJoin\s*\(/,
|
|
333
|
+
/\.innerJoin\s*\(/,
|
|
334
|
+
/\.create\s*\(/,
|
|
335
|
+
/\.createMany\s*\(/,
|
|
336
|
+
/\.aggregate\s*\(/,
|
|
337
|
+
/\.count\s*\(/,
|
|
338
|
+
/\.distinct\s*\(/
|
|
339
|
+
];
|
|
340
|
+
return ormPatterns.some(pattern => pattern.test(text));
|
|
341
|
+
}
|
|
342
|
+
isDatabaseCall(text, patterns) {
|
|
343
|
+
return patterns.some(pattern => text.toLowerCase().includes(pattern.toLowerCase()));
|
|
344
|
+
}
|
|
345
|
+
extractTables(text, config) {
|
|
346
|
+
const tables = new Set();
|
|
347
|
+
// Check ORM patterns
|
|
348
|
+
config.tablePatterns?.orm?.forEach(pattern => {
|
|
349
|
+
const matches = text.matchAll(pattern);
|
|
350
|
+
for (const match of matches) {
|
|
351
|
+
if (match[1])
|
|
352
|
+
tables.add(match[1]);
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
// Check SQL patterns
|
|
356
|
+
config.tablePatterns?.sql?.forEach(pattern => {
|
|
357
|
+
const matches = text.matchAll(pattern);
|
|
358
|
+
for (const match of matches) {
|
|
359
|
+
if (match[1])
|
|
360
|
+
tables.add(match[1]);
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
// Additional check for common ORM patterns that might be missed
|
|
364
|
+
// Handle patterns like db.select().from(users) where 'users' is a variable
|
|
365
|
+
const ormVariablePattern = /\.from\s*\(\s*([a-zA-Z_]\w*)\s*\)/g;
|
|
366
|
+
const ormMatches = text.matchAll(ormVariablePattern);
|
|
367
|
+
for (const match of ormMatches) {
|
|
368
|
+
if (match[1] && !match[1].includes('"') && !match[1].includes("'")) {
|
|
369
|
+
tables.add(match[1]);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
// Handle patterns like db.users.find() or db.orders.findOne()
|
|
373
|
+
const dbTablePattern = /db\.([a-zA-Z_]\w*)\.\w+\s*\(/g;
|
|
374
|
+
const dbMatches = text.matchAll(dbTablePattern);
|
|
375
|
+
for (const match of dbMatches) {
|
|
376
|
+
if (match[1]) {
|
|
377
|
+
tables.add(match[1]);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
return Array.from(tables);
|
|
381
|
+
}
|
|
382
|
+
hasOrganizationFilter(text, config) {
|
|
383
|
+
const patterns = config.organizationPatterns || [];
|
|
384
|
+
const lowerText = text.toLowerCase();
|
|
385
|
+
console.log('[DEBUG] hasOrganizationFilter called with:', {
|
|
386
|
+
text: text.substring(0, 100),
|
|
387
|
+
patternsFromConfig: patterns,
|
|
388
|
+
patternsLength: patterns.length
|
|
389
|
+
});
|
|
390
|
+
// If no patterns provided, check for hardcoded common patterns as fallback
|
|
391
|
+
const fallbackPatterns = patterns.length === 0 ? [
|
|
392
|
+
'organizationid', 'organization_id', 'orgid', 'org_id',
|
|
393
|
+
'tenantid', 'tenant_id', 'companyid', 'company_id'
|
|
394
|
+
] : patterns;
|
|
395
|
+
console.log('[DEBUG] Using fallback patterns:', fallbackPatterns);
|
|
396
|
+
// Check for simple pattern matches first
|
|
397
|
+
const hasSimpleMatch = fallbackPatterns.some(pattern => {
|
|
398
|
+
const match = lowerText.includes(pattern.toLowerCase());
|
|
399
|
+
console.log(`[DEBUG] Pattern "${pattern}" -> "${pattern.toLowerCase()}" in "${lowerText}": ${match}`);
|
|
400
|
+
return match;
|
|
401
|
+
});
|
|
402
|
+
if (hasSimpleMatch) {
|
|
403
|
+
console.log('[DEBUG] Found simple match, returning true');
|
|
404
|
+
return true;
|
|
405
|
+
}
|
|
406
|
+
// Enhanced pattern matching for object properties and SQL WHERE clauses
|
|
407
|
+
for (const pattern of fallbackPatterns) {
|
|
408
|
+
const lowerPattern = pattern.toLowerCase();
|
|
409
|
+
// Check for object property patterns: { organizationId: ... }
|
|
410
|
+
if (lowerText.includes(`${lowerPattern}:`)) {
|
|
411
|
+
return true;
|
|
412
|
+
}
|
|
413
|
+
// Check for object property patterns with quotes: { "organizationId": ... }
|
|
414
|
+
if (lowerText.includes(`"${lowerPattern}"`)) {
|
|
415
|
+
return true;
|
|
416
|
+
}
|
|
417
|
+
// Check for object property patterns with single quotes: { 'organizationId': ... }
|
|
418
|
+
if (lowerText.includes(`'${lowerPattern}'`)) {
|
|
419
|
+
return true;
|
|
420
|
+
}
|
|
421
|
+
// Check for SQL WHERE clause patterns: WHERE organizationId =
|
|
422
|
+
if (lowerText.includes(`where ${lowerPattern} =`) ||
|
|
423
|
+
lowerText.includes(`where ${lowerPattern}=`)) {
|
|
424
|
+
return true;
|
|
425
|
+
}
|
|
426
|
+
// Check for SQL AND clause patterns: AND organizationId =
|
|
427
|
+
if (lowerText.includes(`and ${lowerPattern} =`) ||
|
|
428
|
+
lowerText.includes(`and ${lowerPattern}=`)) {
|
|
429
|
+
return true;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
// Debug logging
|
|
433
|
+
console.log('[DEBUG] hasOrganizationFilter check:', {
|
|
434
|
+
text: text.substring(0, 150),
|
|
435
|
+
patterns,
|
|
436
|
+
fallbackPatterns,
|
|
437
|
+
hasFilter: false
|
|
438
|
+
});
|
|
439
|
+
return false;
|
|
440
|
+
}
|
|
441
|
+
checkQuerySecurity(text, config) {
|
|
442
|
+
const parameterized = (config.securityPatterns?.parameterizedQueries || []).some(pattern => text.includes(pattern));
|
|
443
|
+
// Enhanced SQL injection detection
|
|
444
|
+
const sqlInjectionPatterns = [
|
|
445
|
+
'${', // Template literal interpolation
|
|
446
|
+
'concat', // String concatenation
|
|
447
|
+
'+', // String concatenation with +
|
|
448
|
+
"'${", // Template literal in quotes
|
|
449
|
+
'"${', // Template literal in double quotes
|
|
450
|
+
'` + ', // String concatenation
|
|
451
|
+
'" + ', // String concatenation
|
|
452
|
+
"' + " // String concatenation
|
|
453
|
+
];
|
|
454
|
+
const configPatterns = config.securityPatterns?.sqlInjectionRisks || [];
|
|
455
|
+
const allPatterns = [...sqlInjectionPatterns, ...configPatterns];
|
|
456
|
+
const injectionRisk = allPatterns.some(pattern => text.includes(pattern)) &&
|
|
457
|
+
this.containsSQLKeywords(text);
|
|
458
|
+
return { parameterized, injectionRisk };
|
|
459
|
+
}
|
|
460
|
+
extractMethodName(node, adapter, sourceCode) {
|
|
461
|
+
const text = adapter.getNodeText(node, sourceCode);
|
|
462
|
+
const match = text.match(/(\w+)\s*\(/);
|
|
463
|
+
return match ? match[1] : 'unknown';
|
|
464
|
+
}
|
|
465
|
+
requiresOrgFilter(tables) {
|
|
466
|
+
// Tables that typically need organization filtering
|
|
467
|
+
const orgTables = ['users', 'projects', 'orders', 'customers', 'accounts', 'teams'];
|
|
468
|
+
return tables.some(table => {
|
|
469
|
+
// Handle both actual table names and variable names that likely represent tables
|
|
470
|
+
const tableName = table.toLowerCase();
|
|
471
|
+
// Check exact match or if the table variable name matches (e.g., 'users' variable for 'users' table)
|
|
472
|
+
return orgTables.includes(tableName) || orgTables.some(orgTable => tableName === orgTable);
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
isStringLiteral(node, adapter) {
|
|
476
|
+
return node.type.includes('StringLiteral') || node.type.includes('TemplateLiteral');
|
|
477
|
+
}
|
|
478
|
+
isConnectionString(text) {
|
|
479
|
+
const patterns = [
|
|
480
|
+
/mongodb:\/\//i,
|
|
481
|
+
/postgres:\/\//i,
|
|
482
|
+
/mysql:\/\//i,
|
|
483
|
+
/Server=.*;Database=/i,
|
|
484
|
+
/Data Source=.*;Initial Catalog=/i
|
|
485
|
+
];
|
|
486
|
+
return patterns.some(pattern => pattern.test(text));
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
//# sourceMappingURL=UniversalDataAccessAnalyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UniversalDataAccessAnalyzer.js","sourceRoot":"","sources":["../../../src/analyzers/universal/UniversalDataAccessAnalyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Universal Documentation Analyzer
|
|
3
|
+
* Works across multiple programming languages using the adapter pattern
|
|
4
|
+
*/
|
|
5
|
+
import { UniversalAnalyzer } from '../../languages/UniversalAnalyzer.js';
|
|
6
|
+
import type { Violation } from '../../types.js';
|
|
7
|
+
import type { AST, LanguageAdapter } from '../../languages/types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Configuration for documentation analyzer
|
|
10
|
+
*/
|
|
11
|
+
export interface DocumentationAnalyzerConfig {
|
|
12
|
+
requireFunctionDocs: boolean;
|
|
13
|
+
requireClassDocs: boolean;
|
|
14
|
+
requireFileDocs: boolean;
|
|
15
|
+
requireParamDocs: boolean;
|
|
16
|
+
requireReturnDocs: boolean;
|
|
17
|
+
minDescriptionLength: number;
|
|
18
|
+
checkExportedOnly: boolean;
|
|
19
|
+
exemptPatterns: string[];
|
|
20
|
+
}
|
|
21
|
+
export declare const DEFAULT_DOCUMENTATION_CONFIG: DocumentationAnalyzerConfig;
|
|
22
|
+
export declare class UniversalDocumentationAnalyzer extends UniversalAnalyzer {
|
|
23
|
+
readonly name = "documentation";
|
|
24
|
+
readonly description = "Analyzes documentation quality across the codebase";
|
|
25
|
+
readonly category = "documentation";
|
|
26
|
+
protected analyzeAST(ast: AST, adapter: LanguageAdapter, config: DocumentationAnalyzerConfig, sourceCode: string): Promise<Violation[]>;
|
|
27
|
+
/**
|
|
28
|
+
* Check if a name matches any exempt patterns
|
|
29
|
+
*/
|
|
30
|
+
private isExempt;
|
|
31
|
+
/**
|
|
32
|
+
* Get file-level documentation (usually at the top)
|
|
33
|
+
*/
|
|
34
|
+
private getFileDocumentation;
|
|
35
|
+
/**
|
|
36
|
+
* Find a node by its location
|
|
37
|
+
*/
|
|
38
|
+
private findNodeByLocation;
|
|
39
|
+
/**
|
|
40
|
+
* Check which parameters are missing documentation
|
|
41
|
+
*/
|
|
42
|
+
private checkParameterDocumentation;
|
|
43
|
+
/**
|
|
44
|
+
* Check if documentation contains return value documentation
|
|
45
|
+
*/
|
|
46
|
+
private hasReturnDocumentation;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=UniversalDocumentationAnalyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UniversalDocumentationAnalyzer.d.ts","sourceRoot":"","sources":["../../../src/analyzers/universal/UniversalDocumentationAnalyzer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,GAAG,EAAE,eAAe,EAAW,MAAM,0BAA0B,CAAC;AAE9E;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,mBAAmB,EAAE,OAAO,CAAC;IAC7B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,eAAe,EAAE,OAAO,CAAC;IACzB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,eAAO,MAAM,4BAA4B,EAAE,2BAiB1C,CAAC;AAEF,qBAAa,8BAA+B,SAAQ,iBAAiB;IACnE,QAAQ,CAAC,IAAI,mBAAmB;IAChC,QAAQ,CAAC,WAAW,wDAAwD;IAC5E,QAAQ,CAAC,QAAQ,mBAAmB;cAEpB,UAAU,CACxB,GAAG,EAAE,GAAG,EACR,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,2BAA2B,EACnC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,SAAS,EAAE,CAAC;IAkJvB;;OAEG;IACH,OAAO,CAAC,QAAQ;IAOhB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAS5B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAmB1B;;OAEG;IACH,OAAO,CAAC,2BAA2B;IAcnC;;OAEG;IACH,OAAO,CAAC,sBAAsB;CAI/B"}
|