@sun-asterisk/sunlint 1.3.0 → 1.3.2

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 (124) hide show
  1. package/CHANGELOG.md +115 -1
  2. package/CONTRIBUTING.md +249 -605
  3. package/README.md +3 -4
  4. package/config/ci-cd.json +54 -0
  5. package/config/development.json +56 -0
  6. package/config/large-project.json +143 -0
  7. package/config/presets/all.json +0 -1
  8. package/config/release.json +70 -0
  9. package/config/rule-analysis-strategies.js +38 -3
  10. package/config/rules/enhanced-rules-registry.json +474 -1179
  11. package/config/rules/rules-registry-generated.json +3 -3
  12. package/core/cli-action-handler.js +24 -30
  13. package/core/cli-program.js +11 -3
  14. package/core/config-merger.js +29 -2
  15. package/core/enhanced-rules-registry.js +3 -2
  16. package/core/semantic-engine.js +129 -19
  17. package/core/semantic-rule-base.js +4 -2
  18. package/core/unified-rule-registry.js +1 -1
  19. package/docs/COMMAND-EXAMPLES.md +134 -0
  20. package/docs/LARGE-PROJECT-GUIDE.md +324 -0
  21. package/engines/heuristic-engine.js +135 -16
  22. package/integrations/eslint/plugin/index.js +0 -2
  23. package/integrations/eslint/plugin/rules/common/c003-no-vague-abbreviations.js +59 -1
  24. package/integrations/eslint/plugin/rules/common/c006-function-name-verb-noun.js +26 -1
  25. package/integrations/eslint/plugin/rules/common/c030-use-custom-error-classes.js +54 -19
  26. package/origin-rules/common-en.md +19 -15
  27. package/package.json +1 -1
  28. package/rules/common/C002_no_duplicate_code/analyzer.js +334 -36
  29. package/rules/common/C003_no_vague_abbreviations/analyzer.js +220 -35
  30. package/rules/common/C006_function_naming/analyzer.js +29 -3
  31. package/rules/common/C010_limit_block_nesting/analyzer.js +181 -337
  32. package/rules/common/C010_limit_block_nesting/config.json +64 -0
  33. package/rules/common/C010_limit_block_nesting/regex-based-analyzer.js +379 -0
  34. package/rules/common/C010_limit_block_nesting/symbol-based-analyzer.js +231 -0
  35. package/rules/common/C013_no_dead_code/analyzer.js +75 -177
  36. package/rules/common/C013_no_dead_code/config.json +61 -0
  37. package/rules/common/C013_no_dead_code/regex-based-analyzer.js +345 -0
  38. package/rules/common/C013_no_dead_code/symbol-based-analyzer.js +640 -0
  39. package/rules/common/C014_dependency_injection/analyzer.js +48 -313
  40. package/rules/common/C014_dependency_injection/config.json +26 -0
  41. package/rules/common/C014_dependency_injection/symbol-based-analyzer.js +751 -0
  42. package/rules/common/C017_constructor_logic/analyzer.js +254 -17
  43. package/rules/common/C017_constructor_logic/semantic-analyzer.js +340 -0
  44. package/rules/common/C018_no_throw_generic_error/analyzer.js +232 -0
  45. package/rules/common/C018_no_throw_generic_error/config.json +50 -0
  46. package/rules/common/C018_no_throw_generic_error/regex-based-analyzer.js +387 -0
  47. package/rules/common/C018_no_throw_generic_error/symbol-based-analyzer.js +314 -0
  48. package/rules/common/C019_log_level_usage/analyzer.js +110 -317
  49. package/rules/common/C019_log_level_usage/pattern-analyzer.js +88 -0
  50. package/rules/common/C019_log_level_usage/system-log-analyzer.js +1267 -0
  51. package/rules/common/C023_no_duplicate_variable/analyzer.js +180 -0
  52. package/rules/common/C023_no_duplicate_variable/config.json +50 -0
  53. package/rules/common/C023_no_duplicate_variable/symbol-based-analyzer.js +158 -0
  54. package/rules/common/C024_no_scatter_hardcoded_constants/analyzer.js +180 -0
  55. package/rules/common/C024_no_scatter_hardcoded_constants/config.json +50 -0
  56. package/rules/common/C024_no_scatter_hardcoded_constants/symbol-based-analyzer.js +181 -0
  57. package/rules/common/C030_use_custom_error_classes/analyzer.js +200 -0
  58. package/rules/common/C033_separate_service_repository/README.md +78 -0
  59. package/rules/common/C033_separate_service_repository/analyzer.js +160 -0
  60. package/rules/common/C033_separate_service_repository/config.json +50 -0
  61. package/rules/common/C033_separate_service_repository/regex-based-analyzer.js +585 -0
  62. package/rules/common/C033_separate_service_repository/symbol-based-analyzer.js +368 -0
  63. package/rules/common/C035_error_logging_context/STRATEGY.md +99 -0
  64. package/rules/common/C035_error_logging_context/analyzer.js +232 -0
  65. package/rules/common/C035_error_logging_context/config.json +54 -0
  66. package/rules/common/C035_error_logging_context/regex-based-analyzer.js +299 -0
  67. package/rules/common/C035_error_logging_context/symbol-based-analyzer.js +454 -0
  68. package/rules/common/C040_centralized_validation/analyzer.js +165 -0
  69. package/rules/common/C040_centralized_validation/config.json +46 -0
  70. package/rules/common/C040_centralized_validation/regex-based-analyzer.js +243 -0
  71. package/rules/common/C040_centralized_validation/symbol-based-analyzer.js +416 -0
  72. package/rules/common/{C076_single_test_behavior → C072_single_test_behavior}/analyzer.js +6 -6
  73. package/rules/common/C076_explicit_function_types/README.md +30 -0
  74. package/rules/common/C076_explicit_function_types/analyzer.js +172 -0
  75. package/rules/common/C076_explicit_function_types/config.json +15 -0
  76. package/rules/common/C076_explicit_function_types/semantic-analyzer.js +341 -0
  77. package/rules/index.js +6 -1
  78. package/rules/parser/rule-parser.js +13 -2
  79. package/rules/security/S005_no_origin_auth/README.md +226 -0
  80. package/rules/security/S005_no_origin_auth/analyzer.js +184 -0
  81. package/rules/security/S005_no_origin_auth/ast-analyzer.js +406 -0
  82. package/rules/security/S005_no_origin_auth/config.json +85 -0
  83. package/rules/security/S006_no_plaintext_recovery_codes/README.md +139 -0
  84. package/rules/security/S006_no_plaintext_recovery_codes/analyzer.js +306 -0
  85. package/rules/security/S006_no_plaintext_recovery_codes/config.json +48 -0
  86. package/rules/security/S007_no_plaintext_otp/README.md +198 -0
  87. package/rules/security/S007_no_plaintext_otp/analyzer.js +406 -0
  88. package/rules/security/S007_no_plaintext_otp/config.json +79 -0
  89. package/rules/security/S007_no_plaintext_otp/semantic-analyzer.js +609 -0
  90. package/rules/security/S007_no_plaintext_otp/semantic-config.json +195 -0
  91. package/rules/security/S007_no_plaintext_otp/semantic-wrapper.js +280 -0
  92. package/rules/security/S009_no_insecure_encryption/README.md +158 -0
  93. package/rules/security/S009_no_insecure_encryption/analyzer.js +319 -0
  94. package/rules/security/S009_no_insecure_encryption/config.json +55 -0
  95. package/rules/security/S010_no_insecure_encryption/README.md +224 -0
  96. package/rules/security/S010_no_insecure_encryption/analyzer.js +493 -0
  97. package/rules/security/S010_no_insecure_encryption/config.json +48 -0
  98. package/rules/security/S016_no_sensitive_querystring/STRATEGY.md +149 -0
  99. package/rules/security/S016_no_sensitive_querystring/analyzer.js +276 -0
  100. package/rules/security/S016_no_sensitive_querystring/config.json +127 -0
  101. package/rules/security/S016_no_sensitive_querystring/regex-based-analyzer.js +258 -0
  102. package/rules/security/S016_no_sensitive_querystring/symbol-based-analyzer.js +495 -0
  103. package/rules/security/S027_no_hardcoded_secrets/analyzer.js +180 -366
  104. package/rules/security/S027_no_hardcoded_secrets/categories.json +153 -0
  105. package/rules/security/S027_no_hardcoded_secrets/categorized-analyzer.js +250 -0
  106. package/rules/security/S048_no_current_password_in_reset/README.md +222 -0
  107. package/rules/security/S048_no_current_password_in_reset/analyzer.js +366 -0
  108. package/rules/security/S048_no_current_password_in_reset/config.json +48 -0
  109. package/rules/security/S055_content_type_validation/README.md +176 -0
  110. package/rules/security/S055_content_type_validation/analyzer.js +312 -0
  111. package/rules/security/S055_content_type_validation/config.json +48 -0
  112. package/rules/utils/rule-helpers.js +140 -1
  113. package/scripts/consolidate-config.js +116 -0
  114. package/scripts/prepare-release.sh +1 -1
  115. package/config/rules/rules-registry.json +0 -765
  116. package/docs/ESLINT-INTEGRATION-STRATEGY.md +0 -392
  117. package/docs/FUTURE_PACKAGES.md +0 -83
  118. package/docs/HEURISTIC_VS_AI.md +0 -113
  119. package/docs/PRODUCTION_DEPLOYMENT_ANALYSIS.md +0 -112
  120. package/docs/PRODUCTION_SIZE_IMPACT.md +0 -183
  121. package/docs/RELEASE_GUIDE.md +0 -230
  122. package/docs/STANDARDIZED-CATEGORY-FILTERING.md +0 -156
  123. package/integrations/eslint/plugin/rules/common/c076-single-behavior-per-test.js +0 -254
  124. package/rules/common/C006_function_naming/smart-analyzer.js +0 -503
@@ -0,0 +1,195 @@
1
+ {
2
+ "ruleId": "S007",
3
+ "name": "No Plaintext OTP (Semantic Analysis)",
4
+ "category": "security",
5
+ "severity": "error",
6
+ "type": "semantic",
7
+ "description": "Detects plaintext OTP storage and transmission using semantic analysis with Symbol Table",
8
+
9
+ "analysis": {
10
+ "engine": "semantic",
11
+ "strategy": "symbol-table",
12
+ "crossFileAnalysis": true,
13
+ "requiresTypeChecker": false,
14
+ "cacheResults": true,
15
+ "timeout": 30000,
16
+ "maxFiles": 1000
17
+ },
18
+
19
+ "scope": {
20
+ "fileTypes": [".ts", ".tsx", ".js", ".jsx"],
21
+ "excludePatterns": [
22
+ "**/test/**",
23
+ "**/tests/**",
24
+ "**/__tests__/**",
25
+ "**/*.test.*",
26
+ "**/*.spec.*",
27
+ "**/node_modules/**",
28
+ "**/build/**",
29
+ "**/dist/**"
30
+ ]
31
+ },
32
+
33
+ "semanticPatterns": {
34
+ "otpVariables": {
35
+ "patterns": [
36
+ "^(otp|totp|hotp)$",
37
+ "^(one_?time|onetime)_?(password|pass|code)$",
38
+ "^(auth|verification|sms|temp|security|access|login)_?code$",
39
+ "^(two_?factor|2fa|mfa)_?(token|code)$",
40
+ "^pin_?code$"
41
+ ],
42
+ "caseInsensitive": true
43
+ },
44
+
45
+ "otpFunctions": {
46
+ "patterns": [
47
+ "^(generate|create|store|save|send|validate|verify)_?otp$",
48
+ "^otp_?(generate|create|store|save|send|validate|verify)$",
49
+ "^(generate|create|store|save|send|validate|verify)_?(auth|verification|sms|temp|security|access|login)_?code$",
50
+ "^send_?(sms|email|auth)_?code$"
51
+ ],
52
+ "methodNames": [
53
+ "sendOtp", "storeOtp", "saveOtp", "generateOtp", "verifyOtp",
54
+ "sendSmsCode", "sendAuthCode", "storeAuthCode", "saveAuthCode"
55
+ ]
56
+ },
57
+
58
+ "dangerousOperations": {
59
+ "storage": [
60
+ "save", "store", "insert", "update", "create", "persist",
61
+ "collection.insertOne", "collection.updateOne", "db.save",
62
+ "redis.set", "redis.hset", "cache.put", "cache.set"
63
+ ],
64
+ "transmission": [
65
+ "send", "emit", "post", "put", "response.json", "res.send",
66
+ "email.send", "sms.send", "notify", "broadcast"
67
+ ],
68
+ "browserStorage": [
69
+ "localStorage.setItem", "sessionStorage.setItem",
70
+ "localStorage.set", "sessionStorage.set"
71
+ ],
72
+ "logging": [
73
+ "console.log", "console.debug", "console.info",
74
+ "logger.info", "logger.debug", "log.info"
75
+ ]
76
+ },
77
+
78
+ "safeOperations": [
79
+ "bcrypt.hash", "crypto.createHash", "crypto.createHmac",
80
+ "hash", "encrypt", "cipher", "secure", "pbkdf2",
81
+ "scrypt", "argon2", "aes.encrypt", "rsa.encrypt"
82
+ ]
83
+ },
84
+
85
+ "violations": {
86
+ "types": {
87
+ "semantic_otp_variable_usage": {
88
+ "severity": "error",
89
+ "message": "OTP variable used in {context} without encryption",
90
+ "suggestion": "Encrypt or hash OTP values before {context}"
91
+ },
92
+ "semantic_otp_function_call": {
93
+ "severity": "warning",
94
+ "message": "Function may handle OTP in plaintext",
95
+ "suggestion": "Ensure OTP values are encrypted before processing"
96
+ },
97
+ "semantic_plaintext_otp_argument": {
98
+ "severity": "error",
99
+ "message": "Potential plaintext OTP passed to {operation}",
100
+ "suggestion": "Encrypt or hash OTP values before storage/transmission"
101
+ },
102
+ "semantic_method_chain_otp": {
103
+ "severity": "error",
104
+ "message": "Method chain exposes OTP in plaintext",
105
+ "suggestion": "Use secure methods for OTP handling in method chains"
106
+ },
107
+ "semantic_data_flow_violation": {
108
+ "severity": "error",
109
+ "message": "OTP flows to unsafe operation without encryption",
110
+ "suggestion": "Ensure OTP is encrypted before reaching this operation"
111
+ },
112
+ "semantic_cross_file_otp_violation": {
113
+ "severity": "warning",
114
+ "message": "Imported OTP symbol used unsafely",
115
+ "suggestion": "Ensure consistent OTP security across file boundaries"
116
+ }
117
+ },
118
+
119
+ "severityMapping": {
120
+ "storage": "error",
121
+ "transmission": "error",
122
+ "browser_storage": "warning",
123
+ "logging": "warning",
124
+ "unknown_dangerous": "info"
125
+ }
126
+ },
127
+
128
+ "dataFlow": {
129
+ "enabled": true,
130
+ "maxDistance": 20,
131
+ "trackAcrossFiles": true,
132
+ "trackThroughCallbacks": true,
133
+ "trackAsyncFlows": true
134
+ },
135
+
136
+ "performance": {
137
+ "symbolTableCaching": true,
138
+ "maxAnalysisDepth": 10,
139
+ "maxCrossFileReferences": 100,
140
+ "timeoutPerFile": 5000
141
+ },
142
+
143
+ "reporting": {
144
+ "includeSymbolContext": true,
145
+ "includeCrossFileReferences": true,
146
+ "includeDataFlowPath": true,
147
+ "includeCodeSnippets": true,
148
+ "confidenceThreshold": 0.7
149
+ },
150
+
151
+ "examples": {
152
+ "violations": [
153
+ {
154
+ "description": "Direct OTP storage",
155
+ "code": "const otp = generateOtp(); await user.save({ otp });",
156
+ "reason": "OTP variable flows directly to storage operation"
157
+ },
158
+ {
159
+ "description": "OTP in response",
160
+ "code": "return response.json({ authCode, success: true });",
161
+ "reason": "OTP variable included in API response"
162
+ },
163
+ {
164
+ "description": "Method chain violation",
165
+ "code": "this.otpCode.save();",
166
+ "reason": "OTP flows through method chain to unsafe operation"
167
+ }
168
+ ],
169
+
170
+ "safePatterns": [
171
+ {
172
+ "description": "Encrypted storage",
173
+ "code": "const hashedOtp = await bcrypt.hash(otp, 10); await user.save({ hashedOtp });",
174
+ "reason": "OTP is hashed before storage"
175
+ },
176
+ {
177
+ "description": "Secure transmission",
178
+ "code": "const encrypted = encrypt(otp, key); await send(encrypted);",
179
+ "reason": "OTP is encrypted before transmission"
180
+ }
181
+ ]
182
+ },
183
+
184
+ "metadata": {
185
+ "version": "1.0.0",
186
+ "lastUpdated": "2024-01-20",
187
+ "author": "SunLint Security Team",
188
+ "references": [
189
+ "OWASP A02:2021 - Cryptographic Failures",
190
+ "NIST SP 800-63B - Authentication Guidelines",
191
+ "RFC 6238 - TOTP: Time-Based One-Time Password Algorithm"
192
+ ],
193
+ "tags": ["security", "authentication", "otp", "encryption", "semantic"]
194
+ }
195
+ }
@@ -0,0 +1,280 @@
1
+ /**
2
+ * S007 Semantic Wrapper
3
+ * Integrates S007SemanticAnalyzer with HeuristicEngine
4
+ * Provides compatibility layer between semantic analysis and existing framework
5
+ */
6
+
7
+ const S007SemanticAnalyzer = require('./semantic-analyzer');
8
+ const SemanticRuleBase = require('../../../core/semantic-rule-base');
9
+
10
+ class S007SemanticWrapper extends SemanticRuleBase {
11
+ constructor(options = {}) {
12
+ super('S007', {
13
+ category: 'security',
14
+ severity: 'error',
15
+ description: 'Detects plaintext OTP storage and transmission using semantic analysis',
16
+ crossFileAnalysis: true,
17
+ requiresTypeChecker: false,
18
+ cacheResults: true,
19
+ ...options
20
+ });
21
+
22
+ this.semanticAnalyzer = new S007SemanticAnalyzer('S007');
23
+ this.verbose = options.verbose || false;
24
+ }
25
+
26
+ /**
27
+ * Initialize with semantic engine
28
+ */
29
+ async initialize(semanticEngine) {
30
+ await super.initialize(semanticEngine);
31
+
32
+ // Initialize the semantic analyzer
33
+ await this.semanticAnalyzer.initialize(semanticEngine);
34
+
35
+ if (this.verbose) {
36
+ console.log(`🧠 S007SemanticWrapper initialized with semantic engine`);
37
+ }
38
+ }
39
+
40
+ /**
41
+ * Analyze single file using semantic analysis
42
+ */
43
+ async analyzeFile(filePath, options = {}) {
44
+ if (this.verbose) {
45
+ console.log(`🧠 S007: Analyzing ${filePath} with semantic analysis`);
46
+ }
47
+
48
+ try {
49
+ // Delegate to semantic analyzer
50
+ await this.semanticAnalyzer.analyzeFile(filePath, options);
51
+
52
+ // Get violations from semantic analyzer
53
+ const semanticViolations = this.semanticAnalyzer.getViolations();
54
+
55
+ // Add violations to our collection
56
+ for (const violation of semanticViolations) {
57
+ this.addViolation(violation);
58
+ }
59
+
60
+ // Clear violations from semantic analyzer for next file
61
+ this.semanticAnalyzer.clearViolations();
62
+
63
+ if (this.verbose && semanticViolations.length > 0) {
64
+ console.log(`🧠 S007: Found ${semanticViolations.length} semantic violations in ${filePath}`);
65
+ }
66
+
67
+ } catch (error) {
68
+ console.error(`❌ S007: Semantic analysis failed for ${filePath}:`, error.message);
69
+
70
+ // Fallback to regex analysis if semantic fails
71
+ if (options.fallbackToRegex !== false) {
72
+ await this.fallbackToRegexAnalysis(filePath, options);
73
+ }
74
+ }
75
+ }
76
+
77
+ /**
78
+ * Fallback to regex analysis if semantic analysis fails
79
+ */
80
+ async fallbackToRegexAnalysis(filePath, options) {
81
+ try {
82
+ if (this.verbose) {
83
+ console.log(`⚠️ S007: Falling back to regex analysis for ${filePath}`);
84
+ }
85
+
86
+ // Use the existing regex analyzer as fallback
87
+ const RegexAnalyzer = require('./analyzer');
88
+ const regexAnalyzer = new RegexAnalyzer();
89
+
90
+ const regexViolations = await regexAnalyzer.analyze([filePath], 'typescript', options);
91
+
92
+ // Add regex violations with lower confidence
93
+ for (const violation of regexViolations) {
94
+ this.addViolation({
95
+ ...violation,
96
+ analysisMethod: 'regex_fallback',
97
+ confidence: 0.7, // Lower confidence for fallback
98
+ source: 'regex_analyzer'
99
+ });
100
+ }
101
+
102
+ if (this.verbose && regexViolations.length > 0) {
103
+ console.log(`🔧 S007: Found ${regexViolations.length} regex violations (fallback) in ${filePath}`);
104
+ }
105
+
106
+ } catch (fallbackError) {
107
+ console.error(`❌ S007: Fallback analysis also failed for ${filePath}:`, fallbackError.message);
108
+ }
109
+ }
110
+
111
+ /**
112
+ * Get supported file types
113
+ */
114
+ isValidFileType(filePath) {
115
+ const supportedExtensions = ['.ts', '.tsx', '.js', '.jsx'];
116
+ const path = require('path');
117
+ const ext = path.extname(filePath);
118
+ return supportedExtensions.includes(ext);
119
+ }
120
+
121
+ /**
122
+ * Enhanced violation adding with semantic context
123
+ */
124
+ addViolation(violation) {
125
+ const enhancedViolation = {
126
+ ...violation,
127
+
128
+ // Add semantic metadata
129
+ analysisEngine: 'semantic',
130
+ analysisMethod: violation.analysisMethod || 'semantic',
131
+ confidence: violation.confidence || 0.9,
132
+ timestamp: Date.now(),
133
+
134
+ // Ensure required fields
135
+ ruleId: this.ruleId,
136
+ category: this.config.category,
137
+ severity: violation.severity || this.config.severity,
138
+
139
+ // Add semantic-specific fields
140
+ semanticContext: violation.symbolContext || {},
141
+ crossFileReferences: violation.crossFileReferences || [],
142
+ dataFlowAnalysis: violation.dataFlowAnalysis || null,
143
+
144
+ // Enhanced suggestions for semantic violations
145
+ suggestion: this.enhanceSemanticSuggestion(violation),
146
+
147
+ // Code context
148
+ codeSnippet: violation.codeSnippet || null,
149
+
150
+ // Metadata
151
+ metadata: {
152
+ engineVersion: '3.0',
153
+ analysisType: 'semantic',
154
+ symbolTableUsed: true,
155
+ crossFileAnalysis: this.config.crossFileAnalysis,
156
+ ...violation.metadata
157
+ }
158
+ };
159
+
160
+ super.addViolation(enhancedViolation);
161
+ }
162
+
163
+ /**
164
+ * Enhance suggestions with semantic context
165
+ */
166
+ enhanceSemanticSuggestion(violation) {
167
+ const baseSuggestion = violation.suggestion || 'Ensure OTP security best practices';
168
+
169
+ // Add context-specific suggestions based on semantic analysis
170
+ const contextSuggestions = [];
171
+
172
+ if (violation.symbolContext) {
173
+ const context = violation.symbolContext;
174
+
175
+ if (context.operation) {
176
+ contextSuggestions.push(`Consider replacing '${context.operation}' with a secure alternative`);
177
+ }
178
+
179
+ if (context.dataFlow && context.dataFlow.length > 1) {
180
+ contextSuggestions.push('Review the data flow path to identify where encryption should be applied');
181
+ }
182
+
183
+ if (context.crossFileReferences && context.crossFileReferences.length > 0) {
184
+ contextSuggestions.push('Ensure security measures are consistent across all files using this OTP symbol');
185
+ }
186
+ }
187
+
188
+ // Combine base suggestion with context-specific suggestions
189
+ if (contextSuggestions.length > 0) {
190
+ return `${baseSuggestion}. Additional recommendations: ${contextSuggestions.join('; ')}.`;
191
+ }
192
+
193
+ return baseSuggestion;
194
+ }
195
+
196
+ /**
197
+ * Generate analysis report with semantic insights
198
+ */
199
+ generateReport() {
200
+ const baseReport = super.generateReport();
201
+
202
+ // Add semantic-specific statistics
203
+ const semanticStats = this.calculateSemanticStats();
204
+
205
+ return {
206
+ ...baseReport,
207
+ semanticAnalysis: {
208
+ enabled: true,
209
+ symbolTableUsed: true,
210
+ crossFileAnalysisPerformed: this.config.crossFileAnalysis,
211
+ dataFlowAnalysisPerformed: true,
212
+ statistics: semanticStats
213
+ }
214
+ };
215
+ }
216
+
217
+ /**
218
+ * Calculate semantic analysis statistics
219
+ */
220
+ calculateSemanticStats() {
221
+ const violations = this.getViolations();
222
+
223
+ const stats = {
224
+ totalViolations: violations.length,
225
+ violationsByType: {},
226
+ violationsByContext: {},
227
+ averageConfidence: 0,
228
+ crossFileViolations: 0,
229
+ dataFlowViolations: 0
230
+ };
231
+
232
+ // Analyze violation types and contexts
233
+ for (const violation of violations) {
234
+ // Count by type
235
+ const type = violation.type || 'unknown';
236
+ stats.violationsByType[type] = (stats.violationsByType[type] || 0) + 1;
237
+
238
+ // Count by context
239
+ if (violation.symbolContext && violation.symbolContext.usageContext) {
240
+ const context = violation.symbolContext.usageContext;
241
+ stats.violationsByContext[context] = (stats.violationsByContext[context] || 0) + 1;
242
+ }
243
+
244
+ // Count cross-file violations
245
+ if (violation.crossFileReferences && violation.crossFileReferences.length > 0) {
246
+ stats.crossFileViolations++;
247
+ }
248
+
249
+ // Count data flow violations
250
+ if (violation.dataFlowAnalysis) {
251
+ stats.dataFlowViolations++;
252
+ }
253
+ }
254
+
255
+ // Calculate average confidence
256
+ if (violations.length > 0) {
257
+ const totalConfidence = violations.reduce((sum, v) => sum + (v.confidence || 0.9), 0);
258
+ stats.averageConfidence = totalConfidence / violations.length;
259
+ }
260
+
261
+ return stats;
262
+ }
263
+
264
+ /**
265
+ * Cleanup semantic resources
266
+ */
267
+ async cleanup() {
268
+ if (this.semanticAnalyzer && typeof this.semanticAnalyzer.cleanup === 'function') {
269
+ await this.semanticAnalyzer.cleanup();
270
+ }
271
+
272
+ await super.cleanup();
273
+
274
+ if (this.verbose) {
275
+ console.log(`🧠 S007SemanticWrapper cleanup completed`);
276
+ }
277
+ }
278
+ }
279
+
280
+ module.exports = S007SemanticWrapper;
@@ -0,0 +1,158 @@
1
+ # S009 - No Insecure Encryption Modes, Padding, or Cryptographic Algorithms
2
+
3
+ ## Overview
4
+
5
+ This rule detects the usage of insecure cryptographic algorithms, cipher modes, and padding schemes that are vulnerable to various attacks and should not be used in production code.
6
+
7
+ ## Rule Details
8
+
9
+ **Rule ID**: S009
10
+ **Category**: Security
11
+ **Severity**: Error
12
+ **Engine**: Heuristic
13
+ **OWASP**: A02:2021 - Cryptographic Failures
14
+ **CWE**: CWE-327 - Use of a Broken or Risky Cryptographic Algorithm
15
+
16
+ ## Detected Vulnerabilities
17
+
18
+ ### Insecure Symmetric Encryption Algorithms
19
+ - **DES** (Data Encryption Standard) - 56-bit key, easily broken
20
+ - **3DES/TripleDES** - Deprecated, vulnerable to Sweet32 attack
21
+ - **RC2** - Weak key schedule, vulnerable to related-key attacks
22
+ - **RC4** - Stream cipher with biases, deprecated
23
+ - **Blowfish** - Small block size, vulnerable to birthday attacks
24
+
25
+ ### Insecure Cipher Modes
26
+ - **ECB** (Electronic Codebook) - Reveals patterns in plaintext
27
+ - **No encryption mode specified** - May default to insecure modes
28
+
29
+ ### Insecure Hash Algorithms
30
+ - **MD2, MD4, MD5** - Vulnerable to collision attacks
31
+ - **SHA1** - Deprecated, collision attacks demonstrated
32
+ - **RIPEMD-128/160** - Weaker alternatives to SHA family
33
+
34
+ ### Insecure Padding Schemes
35
+ - **PKCS#1 v1.5** - Vulnerable to padding oracle attacks
36
+ - **No padding** - Can lead to information leakage
37
+
38
+ ### Insecure Key Derivation Functions
39
+ - **PBKDF1** - Limited output length, weak
40
+ - **Simple hash-based KDFs** - Vulnerable to dictionary attacks
41
+
42
+ ## Examples
43
+
44
+ ### ❌ Violations
45
+
46
+ ```typescript
47
+ // Node.js crypto module violations
48
+ const cipher = crypto.createCipher('des', key);
49
+ const hash = crypto.createHash('md5');
50
+ const decipher = crypto.createDecipher('rc4', key);
51
+
52
+ // CryptoJS violations
53
+ const encrypted = CryptoJS.DES.encrypt(data, key);
54
+ const hash = CryptoJS.MD5(data);
55
+ const encrypted = CryptoJS.mode.ECB;
56
+
57
+ // Java violations
58
+ Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
59
+ MessageDigest md = MessageDigest.getInstance("MD5");
60
+
61
+ // .NET violations
62
+ var des = new DESCryptoServiceProvider();
63
+ var md5 = MD5.Create();
64
+
65
+ // Configuration violations
66
+ const config = {
67
+ algorithm: 'des',
68
+ hash: 'md5',
69
+ cipher: 'rc4'
70
+ };
71
+ ```
72
+
73
+ ### ✅ Secure Alternatives
74
+
75
+ ```typescript
76
+ // Secure Node.js crypto usage
77
+ const cipher = crypto.createCipher('aes-256-gcm', key);
78
+ const hash = crypto.createHash('sha256');
79
+ const decipher = crypto.createDecipher('aes-256-cbc', key);
80
+
81
+ // Secure CryptoJS usage
82
+ const encrypted = CryptoJS.AES.encrypt(data, key);
83
+ const hash = CryptoJS.SHA256(data);
84
+ const encrypted = CryptoJS.mode.GCM;
85
+
86
+ // Secure Java usage
87
+ Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
88
+ MessageDigest md = MessageDigest.getInstance("SHA-256");
89
+
90
+ // Secure .NET usage
91
+ var aes = new AesCryptoServiceProvider();
92
+ var sha256 = SHA256.Create();
93
+
94
+ // Secure configuration
95
+ const config = {
96
+ algorithm: 'aes-256-gcm',
97
+ hash: 'sha256',
98
+ cipher: 'aes-256-cbc'
99
+ };
100
+ ```
101
+
102
+ ## Supported Languages
103
+
104
+ - **JavaScript/TypeScript** - Node.js crypto, CryptoJS
105
+ - **Java** - javax.crypto, java.security
106
+ - **C#/.NET** - System.Security.Cryptography
107
+ - **Python** - cryptography, hashlib
108
+ - **Go** - crypto packages
109
+ - **Configuration files** - JSON, YAML, XML
110
+
111
+ ## Detection Patterns
112
+
113
+ The rule uses heuristic analysis to detect:
114
+
115
+ 1. **Direct API calls** with insecure algorithms
116
+ 2. **Configuration settings** specifying weak crypto
117
+ 3. **String literals** containing algorithm names
118
+ 4. **Variable assignments** with insecure values
119
+ 5. **Method chaining** with crypto operations
120
+
121
+ ## False Positive Prevention
122
+
123
+ The rule excludes:
124
+
125
+ - **Comments and documentation**
126
+ - **Import/export statements**
127
+ - **Test files and mock data**
128
+ - **Educational/example code**
129
+ - **Variable names** (not actual usage)
130
+ - **Safe algorithm mentions** in secure contexts
131
+
132
+ ## Remediation
133
+
134
+ ### For Symmetric Encryption
135
+ - Use **AES-256** with secure modes (GCM, CBC)
136
+ - Ensure proper **initialization vectors** (IVs)
137
+ - Use **authenticated encryption** when possible
138
+
139
+ ### For Hashing
140
+ - Use **SHA-256** or stronger (SHA-384, SHA-512)
141
+ - For passwords, use **bcrypt**, **scrypt**, or **Argon2**
142
+ - Avoid hashing for integrity without HMAC
143
+
144
+ ### For Asymmetric Encryption
145
+ - Use **RSA-2048** or stronger, or **ECC P-256+**
146
+ - Use **OAEP padding** for RSA encryption
147
+ - Use **PSS padding** for RSA signatures
148
+
149
+ ### For Key Derivation
150
+ - Use **PBKDF2** with high iteration counts (100,000+)
151
+ - Consider **scrypt** or **Argon2** for better security
152
+ - Use proper **salt** values
153
+
154
+ ## References
155
+
156
+ - [OWASP Cryptographic Storage Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html)
157
+ - [NIST Cryptographic Standards](https://csrc.nist.gov/projects/cryptographic-standards-and-guidelines)
158
+ - [RFC 8018 - PKCS #5: Password-Based Cryptography Specification](https://tools.ietf.org/html/rfc8018)