@sun-asterisk/sunlint 1.3.1 → 1.3.3

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 (120) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/CONTRIBUTING.md +210 -1691
  3. package/README.md +5 -3
  4. package/config/rule-analysis-strategies.js +17 -1
  5. package/config/rules/enhanced-rules-registry.json +506 -1161
  6. package/config/rules/rules-registry-generated.json +1 -1
  7. package/core/analysis-orchestrator.js +167 -42
  8. package/core/auto-performance-manager.js +243 -0
  9. package/core/cli-action-handler.js +9 -1
  10. package/core/cli-program.js +19 -5
  11. package/core/constants/defaults.js +56 -0
  12. package/core/enhanced-rules-registry.js +2 -1
  13. package/core/performance-optimizer.js +271 -0
  14. package/core/semantic-engine.js +15 -3
  15. package/core/semantic-rule-base.js +4 -2
  16. package/docs/FILE_LIMITS_COMPLETION_REPORT.md +151 -0
  17. package/docs/FILE_LIMITS_EXPLANATION.md +190 -0
  18. package/docs/PERFORMANCE.md +311 -0
  19. package/docs/PERFORMANCE_MIGRATION_GUIDE.md +368 -0
  20. package/docs/PERFORMANCE_OPTIMIZATION_PLAN.md +255 -0
  21. package/docs/QUICK_FILE_LIMITS.md +64 -0
  22. package/docs/SIMPLIFIED_USAGE_GUIDE.md +208 -0
  23. package/engines/heuristic-engine.js +247 -9
  24. package/integrations/eslint/plugin/rules/common/c003-no-vague-abbreviations.js +59 -1
  25. package/integrations/eslint/plugin/rules/common/c006-function-name-verb-noun.js +26 -1
  26. package/integrations/eslint/plugin/rules/common/c030-use-custom-error-classes.js +54 -19
  27. package/origin-rules/common-en.md +11 -7
  28. package/package.json +2 -1
  29. package/rules/common/C002_no_duplicate_code/analyzer.js +334 -36
  30. package/rules/common/C003_no_vague_abbreviations/analyzer.js +220 -35
  31. package/rules/common/C006_function_naming/analyzer.js +29 -3
  32. package/rules/common/C010_limit_block_nesting/analyzer.js +181 -337
  33. package/rules/common/C010_limit_block_nesting/config.json +64 -0
  34. package/rules/common/C010_limit_block_nesting/regex-based-analyzer.js +379 -0
  35. package/rules/common/C010_limit_block_nesting/symbol-based-analyzer.js +231 -0
  36. package/rules/common/C013_no_dead_code/analyzer.js +75 -177
  37. package/rules/common/C013_no_dead_code/config.json +61 -0
  38. package/rules/common/C013_no_dead_code/regex-based-analyzer.js +345 -0
  39. package/rules/common/C013_no_dead_code/symbol-based-analyzer.js +640 -0
  40. package/rules/common/C014_dependency_injection/analyzer.js +48 -313
  41. package/rules/common/C014_dependency_injection/config.json +26 -0
  42. package/rules/common/C014_dependency_injection/symbol-based-analyzer.js +751 -0
  43. package/rules/common/C018_no_throw_generic_error/analyzer.js +232 -0
  44. package/rules/common/C018_no_throw_generic_error/config.json +50 -0
  45. package/rules/common/C018_no_throw_generic_error/regex-based-analyzer.js +387 -0
  46. package/rules/common/C018_no_throw_generic_error/symbol-based-analyzer.js +314 -0
  47. package/rules/common/C019_log_level_usage/analyzer.js +110 -317
  48. package/rules/common/C019_log_level_usage/pattern-analyzer.js +88 -0
  49. package/rules/common/C019_log_level_usage/system-log-analyzer.js +1267 -0
  50. package/rules/common/C023_no_duplicate_variable/analyzer.js +180 -0
  51. package/rules/common/C023_no_duplicate_variable/config.json +50 -0
  52. package/rules/common/C023_no_duplicate_variable/symbol-based-analyzer.js +158 -0
  53. package/rules/common/C024_no_scatter_hardcoded_constants/analyzer.js +180 -0
  54. package/rules/common/C024_no_scatter_hardcoded_constants/config.json +50 -0
  55. package/rules/common/C024_no_scatter_hardcoded_constants/symbol-based-analyzer.js +181 -0
  56. package/rules/common/C030_use_custom_error_classes/analyzer.js +200 -0
  57. package/rules/common/C035_error_logging_context/analyzer.js +3 -1
  58. package/rules/common/C048_no_bypass_architectural_layers/analyzer.js +180 -0
  59. package/rules/common/C048_no_bypass_architectural_layers/config.json +50 -0
  60. package/rules/common/C048_no_bypass_architectural_layers/symbol-based-analyzer.js +235 -0
  61. package/rules/common/C052_parsing_or_data_transformation/analyzer.js +180 -0
  62. package/rules/common/C052_parsing_or_data_transformation/config.json +50 -0
  63. package/rules/common/C052_parsing_or_data_transformation/symbol-based-analyzer.js +132 -0
  64. package/rules/index.js +7 -1
  65. package/rules/security/S009_no_insecure_encryption/README.md +158 -0
  66. package/rules/security/S009_no_insecure_encryption/analyzer.js +319 -0
  67. package/rules/security/S009_no_insecure_encryption/config.json +55 -0
  68. package/rules/security/S010_no_insecure_encryption/README.md +224 -0
  69. package/rules/security/S010_no_insecure_encryption/analyzer.js +493 -0
  70. package/rules/security/S010_no_insecure_encryption/config.json +48 -0
  71. package/rules/security/S016_no_sensitive_querystring/STRATEGY.md +149 -0
  72. package/rules/security/S016_no_sensitive_querystring/analyzer.js +276 -0
  73. package/rules/security/S016_no_sensitive_querystring/config.json +127 -0
  74. package/rules/security/S016_no_sensitive_querystring/regex-based-analyzer.js +258 -0
  75. package/rules/security/S016_no_sensitive_querystring/symbol-based-analyzer.js +495 -0
  76. package/rules/security/S017_use_parameterized_queries/README.md +128 -0
  77. package/rules/security/S017_use_parameterized_queries/analyzer.js +286 -0
  78. package/rules/security/S017_use_parameterized_queries/config.json +109 -0
  79. package/rules/security/S017_use_parameterized_queries/regex-based-analyzer.js +541 -0
  80. package/rules/security/S017_use_parameterized_queries/symbol-based-analyzer.js +777 -0
  81. package/rules/security/S031_secure_session_cookies/README.md +127 -0
  82. package/rules/security/S031_secure_session_cookies/analyzer.js +245 -0
  83. package/rules/security/S031_secure_session_cookies/config.json +86 -0
  84. package/rules/security/S031_secure_session_cookies/regex-based-analyzer.js +196 -0
  85. package/rules/security/S031_secure_session_cookies/symbol-based-analyzer.js +1084 -0
  86. package/rules/security/S032_httponly_session_cookies/FRAMEWORK_SUPPORT.md +209 -0
  87. package/rules/security/S032_httponly_session_cookies/README.md +184 -0
  88. package/rules/security/S032_httponly_session_cookies/analyzer.js +282 -0
  89. package/rules/security/S032_httponly_session_cookies/config.json +96 -0
  90. package/rules/security/S032_httponly_session_cookies/regex-based-analyzer.js +715 -0
  91. package/rules/security/S032_httponly_session_cookies/symbol-based-analyzer.js +1348 -0
  92. package/rules/security/S033_samesite_session_cookies/README.md +227 -0
  93. package/rules/security/S033_samesite_session_cookies/analyzer.js +242 -0
  94. package/rules/security/S033_samesite_session_cookies/config.json +87 -0
  95. package/rules/security/S033_samesite_session_cookies/regex-based-analyzer.js +703 -0
  96. package/rules/security/S033_samesite_session_cookies/symbol-based-analyzer.js +732 -0
  97. package/rules/security/S034_host_prefix_session_cookies/README.md +204 -0
  98. package/rules/security/S034_host_prefix_session_cookies/analyzer.js +290 -0
  99. package/rules/security/S034_host_prefix_session_cookies/config.json +62 -0
  100. package/rules/security/S034_host_prefix_session_cookies/regex-based-analyzer.js +478 -0
  101. package/rules/security/S034_host_prefix_session_cookies/symbol-based-analyzer.js +277 -0
  102. package/rules/security/S035_path_session_cookies/README.md +257 -0
  103. package/rules/security/S035_path_session_cookies/analyzer.js +316 -0
  104. package/rules/security/S035_path_session_cookies/config.json +99 -0
  105. package/rules/security/S035_path_session_cookies/regex-based-analyzer.js +724 -0
  106. package/rules/security/S035_path_session_cookies/symbol-based-analyzer.js +373 -0
  107. package/rules/security/S048_no_current_password_in_reset/README.md +222 -0
  108. package/rules/security/S048_no_current_password_in_reset/analyzer.js +366 -0
  109. package/rules/security/S048_no_current_password_in_reset/config.json +48 -0
  110. package/rules/security/S055_content_type_validation/README.md +176 -0
  111. package/rules/security/S055_content_type_validation/analyzer.js +312 -0
  112. package/rules/security/S055_content_type_validation/config.json +48 -0
  113. package/rules/utils/rule-helpers.js +140 -1
  114. package/scripts/batch-processing-demo.js +334 -0
  115. package/scripts/consolidate-config.js +116 -0
  116. package/scripts/performance-test.js +541 -0
  117. package/scripts/quick-performance-test.js +108 -0
  118. package/config/rules/S027-categories.json +0 -122
  119. package/config/rules/rules-registry.json +0 -777
  120. package/rules/common/C006_function_naming/smart-analyzer.js +0 -503
@@ -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)
@@ -0,0 +1,319 @@
1
+ /**
2
+ * Heuristic analyzer for S009 - No Insecure Encryption Modes, Padding, or Cryptographic Algorithms
3
+ * Purpose: Detect usage of insecure encryption algorithms, modes, and padding schemes
4
+ * Based on OWASP A02:2021 - Cryptographic Failures
5
+ */
6
+
7
+ class S009Analyzer {
8
+ constructor() {
9
+ this.ruleId = 'S009';
10
+ this.ruleName = 'No Insecure Encryption Modes, Padding, or Cryptographic Algorithms';
11
+ this.description = 'Do not use insecure encryption modes, padding, or cryptographic algorithms';
12
+
13
+ // Insecure symmetric encryption algorithms
14
+ this.insecureSymmetricAlgorithms = [
15
+ 'des', 'des-cbc', 'des-ecb', 'des-cfb', 'des-ofb',
16
+ '3des', 'des-ede', 'des-ede-cbc', 'des-ede-cfb', 'des-ede-ofb',
17
+ 'des-ede3', 'des-ede3-cbc', 'des-ede3-cfb', 'des-ede3-ofb',
18
+ 'rc2', 'rc2-cbc', 'rc2-ecb', 'rc2-cfb', 'rc2-ofb',
19
+ 'rc4', 'rc4-40', 'rc4-hmac-md5',
20
+ 'blowfish', 'bf', 'bf-cbc', 'bf-ecb', 'bf-cfb', 'bf-ofb'
21
+ ];
22
+
23
+ // Insecure block cipher modes
24
+ this.insecureModes = [
25
+ 'ecb', 'electronic-codebook'
26
+ ];
27
+
28
+ // Insecure padding schemes
29
+ this.insecurePadding = [
30
+ 'pkcs1', 'pkcs1_5', 'pkcs1-padding', 'rsa_pkcs1_padding',
31
+ 'no-padding', 'nopadding'
32
+ ];
33
+
34
+ // Insecure hash algorithms
35
+ this.insecureHashAlgorithms = [
36
+ 'md2', 'md4', 'md5',
37
+ 'sha', 'sha1', 'sha-1',
38
+ 'ripemd', 'ripemd128', 'ripemd160'
39
+ ];
40
+
41
+ // Insecure key derivation functions
42
+ this.insecureKDFs = [
43
+ 'pbkdf1', 'simple-hash', 'plain-hash'
44
+ ];
45
+
46
+ // Common crypto libraries and their patterns
47
+ this.cryptoPatterns = [
48
+ // Node.js crypto module
49
+ /crypto\.createCipher\(['"`]([^'"`]+)['"`]/i,
50
+ /crypto\.createDecipher\(['"`]([^'"`]+)['"`]/i,
51
+ /crypto\.createHash\(['"`]([^'"`]+)['"`]/i,
52
+ /crypto\.createHmac\(['"`]([^'"`]+)['"`]/i,
53
+ /crypto\.pbkdf2\(['"`]([^'"`]+)['"`]/i,
54
+
55
+ // CryptoJS patterns
56
+ /CryptoJS\.DES\./i,
57
+ /CryptoJS\.TripleDES\./i,
58
+ /CryptoJS\.RC4\./i,
59
+ /CryptoJS\.MD5\(/i,
60
+ /CryptoJS\.SHA1\(/i,
61
+ /CryptoJS\.mode\.ECB/i,
62
+
63
+ // Java crypto patterns
64
+ /Cipher\.getInstance\(['"`]([^'"`]+)['"`]/i,
65
+ /MessageDigest\.getInstance\(['"`]([^'"`]+)['"`]/i,
66
+ /Mac\.getInstance\(['"`]([^'"`]+)['"`]/i,
67
+ /KeyGenerator\.getInstance\(['"`]([^'"`]+)['"`]/i,
68
+
69
+ // .NET crypto patterns
70
+ /new\s+(DES|TripleDES|RC2|MD5|SHA1)CryptoServiceProvider/i,
71
+ /\.Create\(['"`](DES|TripleDES|RC2|MD5|SHA1)['"`]\)/i,
72
+
73
+ // OpenSSL command patterns
74
+ /-des\b|-des3\b|-rc4\b|-md5\b|-sha1\b/i,
75
+
76
+ // Generic algorithm references
77
+ /'(des|3des|rc4|md5|sha1|ecb)'/i,
78
+ /"(des|3des|rc4|md5|sha1|ecb)"/i,
79
+ /`(des|3des|rc4|md5|sha1|ecb)`/i,
80
+
81
+ // Configuration patterns
82
+ /algorithm\s*[:=]\s*['"`]([^'"`]+)['"`]/i,
83
+ /cipher\s*[:=]\s*['"`]([^'"`]+)['"`]/i,
84
+ /hash\s*[:=]\s*['"`]([^'"`]+)['"`]/i,
85
+ /encryption\s*[:=]\s*['"`]([^'"`]+)['"`]/i,
86
+ ];
87
+
88
+ // Safe patterns to avoid false positives
89
+ this.safePatterns = [
90
+ // Comments and documentation
91
+ /\/\/|\/\*|\*\/|@param|@return|@example|@deprecated|TODO|FIXME/i,
92
+
93
+ // Import/export statements
94
+ /import|export|require|module\.exports/i,
95
+
96
+ // Type definitions
97
+ /interface|type|enum|class.*\{/i,
98
+
99
+ // Test files and mock data
100
+ /\.test\.|\.spec\.|mock|stub|fake|dummy/i,
101
+
102
+ // Safe modern algorithms mentioned in context
103
+ /aes|rsa-oaep|sha256|sha384|sha512|bcrypt|scrypt|argon2|pbkdf2/i,
104
+
105
+ // Configuration examples or documentation
106
+ /example|sample|demo|deprecated|legacy|old|insecure|weak|avoid|don't use|do not use/i,
107
+
108
+ // Variable names that might contain keywords but are safe
109
+ /const\s+\w*[Nn]ame|let\s+\w*[Nn]ame|var\s+\w*[Nn]ame/i,
110
+
111
+ // Safe usage in educational context
112
+ /educational|tutorial|learning|history|comparison/i,
113
+ ];
114
+
115
+ // Context patterns that increase confidence of violations
116
+ this.violationContexts = [
117
+ // Direct algorithm usage
118
+ /encrypt|decrypt|cipher|hash|digest|sign|verify/i,
119
+
120
+ // Configuration settings
121
+ /config|setting|option|parameter/i,
122
+
123
+ // API calls
124
+ /\.create|\.get|\.set|\.use|\.apply/i,
125
+
126
+ // Assignment patterns
127
+ /=\s*['"`]|:\s*['"`]/,
128
+
129
+ // Function calls
130
+ /\([^)]*['"`][^'"`]*['"`][^)]*\)/,
131
+ ];
132
+ }
133
+
134
+ async analyze(files, language, options = {}) {
135
+ const violations = [];
136
+
137
+ for (const filePath of files) {
138
+ // Skip test files, build directories, and node_modules
139
+ if (this.shouldSkipFile(filePath)) {
140
+ continue;
141
+ }
142
+
143
+ try {
144
+ const content = require('fs').readFileSync(filePath, 'utf8');
145
+ const fileViolations = this.analyzeFile(content, filePath, options);
146
+ violations.push(...fileViolations);
147
+ } catch (error) {
148
+ if (options.verbose) {
149
+ console.warn(`⚠️ Failed to analyze ${filePath}: ${error.message}`);
150
+ }
151
+ }
152
+ }
153
+
154
+ return violations;
155
+ }
156
+
157
+ shouldSkipFile(filePath) {
158
+ const skipPatterns = [
159
+ 'test/', 'tests/', '__tests__/', '.test.', '.spec.',
160
+ 'node_modules/', 'build/', 'dist/', '.next/', 'coverage/',
161
+ 'vendor/', 'mocks/', '.mock.', 'docs/', 'documentation/'
162
+ ];
163
+
164
+ return skipPatterns.some(pattern => filePath.includes(pattern));
165
+ }
166
+
167
+ analyzeFile(content, filePath, options = {}) {
168
+ const violations = [];
169
+ const lines = content.split('\n');
170
+
171
+ lines.forEach((line, index) => {
172
+ const lineNumber = index + 1;
173
+ const trimmedLine = line.trim();
174
+
175
+ // Skip comments, imports, and empty lines
176
+ if (this.shouldSkipLine(trimmedLine)) {
177
+ return;
178
+ }
179
+
180
+ // Check for insecure cryptographic usage
181
+ const violation = this.checkForInsecureCrypto(line, lineNumber, filePath);
182
+ if (violation) {
183
+ violations.push(violation);
184
+ }
185
+ });
186
+
187
+ return violations;
188
+ }
189
+
190
+ shouldSkipLine(line) {
191
+ // Skip comments, imports, and other non-code lines
192
+ return (
193
+ line.length === 0 ||
194
+ line.startsWith('//') ||
195
+ line.startsWith('/*') ||
196
+ line.startsWith('*') ||
197
+ line.startsWith('import ') ||
198
+ line.startsWith('export ') ||
199
+ line.startsWith('require(') ||
200
+ line.includes('module.exports') ||
201
+ line.startsWith('#') // Python/shell comments
202
+ );
203
+ }
204
+
205
+ checkForInsecureCrypto(line, lineNumber, filePath) {
206
+ // First check if line contains safe patterns (early exit)
207
+ if (this.containsSafePattern(line)) {
208
+ return null;
209
+ }
210
+
211
+ // Check each crypto pattern
212
+ for (const pattern of this.cryptoPatterns) {
213
+ const match = pattern.exec(line);
214
+ if (match) {
215
+ const algorithm = match[1] ? match[1].toLowerCase() : '';
216
+ const fullMatch = match[0];
217
+
218
+ // Check if the algorithm is insecure
219
+ const insecureAlgorithm = this.identifyInsecureAlgorithm(algorithm, fullMatch);
220
+ if (insecureAlgorithm) {
221
+ // Additional context check to reduce false positives
222
+ if (this.hasViolationContext(line)) {
223
+ return {
224
+ ruleId: this.ruleId,
225
+ severity: 'error',
226
+ message: `Insecure cryptographic algorithm detected: ${insecureAlgorithm.algorithm}. ${insecureAlgorithm.reason}`,
227
+ line: lineNumber,
228
+ column: line.indexOf(fullMatch) + 1,
229
+ filePath: filePath,
230
+ type: insecureAlgorithm.type,
231
+ algorithm: insecureAlgorithm.algorithm,
232
+ details: insecureAlgorithm.recommendation
233
+ };
234
+ }
235
+ }
236
+ }
237
+ }
238
+
239
+ return null;
240
+ }
241
+
242
+ containsSafePattern(line) {
243
+ return this.safePatterns.some(pattern => pattern.test(line));
244
+ }
245
+
246
+ identifyInsecureAlgorithm(algorithm, fullMatch) {
247
+ const lowerAlgorithm = algorithm.toLowerCase();
248
+ const lowerFullMatch = fullMatch.toLowerCase();
249
+
250
+ // Check symmetric encryption algorithms
251
+ if (this.insecureSymmetricAlgorithms.some(alg =>
252
+ lowerAlgorithm.includes(alg) || lowerFullMatch.includes(alg))) {
253
+ const matchedAlg = this.insecureSymmetricAlgorithms.find(alg =>
254
+ lowerAlgorithm.includes(alg) || lowerFullMatch.includes(alg));
255
+
256
+ return {
257
+ algorithm: matchedAlg.toUpperCase(),
258
+ type: 'insecure_symmetric_encryption',
259
+ reason: 'This algorithm is cryptographically weak and vulnerable to attacks.',
260
+ recommendation: 'Use AES-256-GCM or ChaCha20-Poly1305 for symmetric encryption.'
261
+ };
262
+ }
263
+
264
+ // Check block cipher modes
265
+ if (this.insecureModes.some(mode =>
266
+ lowerAlgorithm.includes(mode) || lowerFullMatch.includes(mode))) {
267
+ return {
268
+ algorithm: 'ECB Mode',
269
+ type: 'insecure_cipher_mode',
270
+ reason: 'ECB mode reveals patterns in plaintext and is not semantically secure.',
271
+ recommendation: 'Use CBC, CTR, or GCM modes with proper initialization vectors.'
272
+ };
273
+ }
274
+
275
+ // Check hash algorithms
276
+ if (this.insecureHashAlgorithms.some(hash =>
277
+ lowerAlgorithm.includes(hash) || lowerFullMatch.includes(hash))) {
278
+ const matchedHash = this.insecureHashAlgorithms.find(hash =>
279
+ lowerAlgorithm.includes(hash) || lowerFullMatch.includes(hash));
280
+
281
+ return {
282
+ algorithm: matchedHash.toUpperCase(),
283
+ type: 'insecure_hash_algorithm',
284
+ reason: 'This hash algorithm is vulnerable to collision attacks.',
285
+ recommendation: 'Use SHA-256, SHA-384, or SHA-512 for cryptographic hashing.'
286
+ };
287
+ }
288
+
289
+ // Check padding schemes
290
+ if (this.insecurePadding.some(padding =>
291
+ lowerAlgorithm.includes(padding) || lowerFullMatch.includes(padding))) {
292
+ return {
293
+ algorithm: 'PKCS#1 v1.5 Padding',
294
+ type: 'insecure_padding_scheme',
295
+ reason: 'PKCS#1 v1.5 padding is vulnerable to padding oracle attacks.',
296
+ recommendation: 'Use OAEP padding for RSA encryption.'
297
+ };
298
+ }
299
+
300
+ // Check key derivation functions
301
+ if (this.insecureKDFs.some(kdf =>
302
+ lowerAlgorithm.includes(kdf) || lowerFullMatch.includes(kdf))) {
303
+ return {
304
+ algorithm: 'PBKDF1',
305
+ type: 'insecure_key_derivation',
306
+ reason: 'This key derivation function is weak and vulnerable to attacks.',
307
+ recommendation: 'Use PBKDF2 with high iteration count, scrypt, or Argon2.'
308
+ };
309
+ }
310
+
311
+ return null;
312
+ }
313
+
314
+ hasViolationContext(line) {
315
+ return this.violationContexts.some(context => context.test(line));
316
+ }
317
+ }
318
+
319
+ module.exports = S009Analyzer;
@@ -0,0 +1,55 @@
1
+ {
2
+ "ruleId": "S009",
3
+ "name": "No Insecure Encryption Modes, Padding, or Cryptographic Algorithms",
4
+ "description": "Do not use insecure encryption modes, padding, or cryptographic algorithms",
5
+ "category": "security",
6
+ "severity": "error",
7
+ "languages": ["All languages"],
8
+ "tags": ["security", "owasp", "cryptographic-failures", "encryption"],
9
+ "enabled": true,
10
+ "fixable": false,
11
+ "engine": "heuristic",
12
+ "metadata": {
13
+ "owaspCategory": "A02:2021 - Cryptographic Failures",
14
+ "cweId": "CWE-327",
15
+ "description": "Using insecure cryptographic algorithms, cipher modes, or padding schemes can lead to data exposure and compromise. Weak algorithms like DES, 3DES, RC4, MD5, and SHA1 are vulnerable to various attacks including collision attacks, brute force, and cryptanalysis.",
16
+ "impact": "High - Data exposure, integrity compromise, authentication bypass",
17
+ "likelihood": "Medium",
18
+ "remediation": "Use strong cryptographic algorithms (AES-256, RSA-2048+, SHA-256+), secure cipher modes (GCM, CBC with IV), and proper padding schemes (OAEP)"
19
+ },
20
+ "patterns": {
21
+ "vulnerable": [
22
+ "Using DES or 3DES for encryption",
23
+ "Using RC4 stream cipher",
24
+ "Using ECB cipher mode",
25
+ "Using MD5 or SHA1 for cryptographic purposes",
26
+ "Using PKCS#1 v1.5 padding for RSA",
27
+ "Using weak key derivation functions"
28
+ ],
29
+ "secure": [
30
+ "Using AES-256-GCM for symmetric encryption",
31
+ "Using RSA with OAEP padding",
32
+ "Using SHA-256 or stronger hash algorithms",
33
+ "Using proper cipher modes with initialization vectors",
34
+ "Using PBKDF2, scrypt, or Argon2 for key derivation"
35
+ ]
36
+ },
37
+ "examples": {
38
+ "violations": [
39
+ "crypto.createCipher('des', key);",
40
+ "crypto.createHash('md5');",
41
+ "Cipher.getInstance('DES/ECB/PKCS5Padding');",
42
+ "CryptoJS.DES.encrypt(data, key);",
43
+ "algorithm: 'rc4'",
44
+ "new DESCryptoServiceProvider();"
45
+ ],
46
+ "fixes": [
47
+ "crypto.createCipher('aes-256-gcm', key);",
48
+ "crypto.createHash('sha256');",
49
+ "Cipher.getInstance('AES/GCM/NoPadding');",
50
+ "CryptoJS.AES.encrypt(data, key);",
51
+ "algorithm: 'aes-256-gcm'",
52
+ "new AesCryptoServiceProvider();"
53
+ ]
54
+ }
55
+ }