@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,224 @@
1
+ # S010 - Must use cryptographically secure random number generators (CSPRNG)
2
+
3
+ ## Overview
4
+ Quy tắc này phát hiện việc sử dụng các hàm tạo số ngẫu nhiên không an toàn (như `Math.random()`) cho các mục đích bảo mật, có thể dẫn đến các lỗ hổng bảo mật nghiêm trọng do tính có thể dự đoán được.
5
+
6
+ ## OWASP Classification
7
+ - **Category**: A02:2021 - Cryptographic Failures
8
+ - **CWE**: CWE-338 - Use of Cryptographically Weak Pseudo-Random Number Generator (PRNG)
9
+ - **Severity**: Error
10
+ - **Impact**: High (Predictable tokens, weak encryption keys, authentication bypass)
11
+
12
+ ## Vấn đề
13
+ Khi sử dụng các hàm tạo số ngẫu nhiên không an toàn cho mục đích bảo mật:
14
+
15
+ 1. **Tính dự đoán**: `Math.random()` và các hàm tương tự có thể được dự đoán bởi kẻ tấn công
16
+ 2. **Weak entropy**: Không đủ entropy để tạo ra các giá trị thực sự ngẫu nhiên
17
+ 3. **Seed attacks**: Có thể bị tấn công thông qua việc dự đoán seed
18
+ 4. **Brute force**: Dễ dàng bị brute force do không gian giá trị hạn chế
19
+
20
+ ## Các trường hợp vi phạm
21
+
22
+ ### 1. Sử dụng Math.random() cho security tokens
23
+ ```javascript
24
+ // ❌ Vi phạm - Math.random() không an toàn cho security
25
+ const sessionToken = Math.random().toString(36).substring(2);
26
+ const apiKey = Math.floor(Math.random() * 1000000);
27
+ const resetCode = Math.random().toString().substring(2, 8);
28
+
29
+ // ❌ Vi phạm - tạo password reset token
30
+ function generateResetToken() {
31
+ return Math.random().toString(36).substring(2, 15) +
32
+ Math.random().toString(36).substring(2, 15);
33
+ }
34
+
35
+ // ❌ Vi phạm - tạo JWT secret
36
+ const jwtSecret = Math.random().toString(36);
37
+ ```
38
+
39
+ ### 2. Sử dụng timestamp cho random generation
40
+ ```javascript
41
+ // ❌ Vi phạm - timestamp có thể dự đoán được
42
+ const userId = Date.now().toString();
43
+ const sessionId = new Date().getTime().toString();
44
+ const nonce = performance.now().toString();
45
+
46
+ // ❌ Vi phạm - kết hợp timestamp với Math.random()
47
+ const token = Date.now() + '-' + Math.random().toString(36);
48
+ ```
49
+
50
+ ### 3. Sử dụng cho mã hóa và authentication
51
+ ```javascript
52
+ // ❌ Vi phạm - tạo encryption key không an toàn
53
+ const encryptionKey = Math.random().toString(36).repeat(3);
54
+
55
+ // ❌ Vi phạm - tạo salt cho password hashing
56
+ const salt = Math.random().toString(36).substring(2);
57
+ bcrypt.hash(password, salt); // Nguy hiểm!
58
+
59
+ // ❌ Vi phạm - tạo CSRF token
60
+ const csrfToken = Math.floor(Math.random() * 1000000000);
61
+ ```
62
+
63
+ ### 4. Tạo unique identifiers không an toàn
64
+ ```javascript
65
+ // ❌ Vi phạm - tạo user ID
66
+ const generateUserId = () => Math.random().toString(36).substring(2);
67
+
68
+ // ❌ Vi phạm - tạo file upload path
69
+ const uploadPath = `/uploads/${Math.random().toString(36)}/file.jpg`;
70
+
71
+ // ❌ Vi phạm - tạo temporary filename
72
+ const tempFile = `temp_${Date.now()}_${Math.random()}.tmp`;
73
+ ```
74
+
75
+ ## Giải pháp an toàn
76
+
77
+ ### 1. Sử dụng crypto.randomBytes()
78
+ ```javascript
79
+ // ✅ An toàn - sử dụng crypto.randomBytes()
80
+ const crypto = require('crypto');
81
+
82
+ const sessionToken = crypto.randomBytes(32).toString('hex');
83
+ const apiKey = crypto.randomBytes(16).toString('base64');
84
+ const resetCode = crypto.randomBytes(3).toString('hex'); // 6 hex chars
85
+ ```
86
+
87
+ ### 2. Sử dụng crypto.randomUUID()
88
+ ```javascript
89
+ // ✅ An toàn - sử dụng crypto.randomUUID()
90
+ const sessionId = crypto.randomUUID();
91
+ const userId = crypto.randomUUID();
92
+ const requestId = crypto.randomUUID();
93
+ ```
94
+
95
+ ### 3. Sử dụng crypto.randomInt()
96
+ ```javascript
97
+ // ✅ An toàn - sử dụng crypto.randomInt()
98
+ const otpCode = crypto.randomInt(100000, 999999); // 6-digit OTP
99
+ const randomPort = crypto.randomInt(3000, 9000);
100
+ const challengeNumber = crypto.randomInt(1, 1000000);
101
+ ```
102
+
103
+ ### 4. Sử dụng cho mã hóa an toàn
104
+ ```javascript
105
+ // ✅ An toàn - tạo encryption key
106
+ const encryptionKey = crypto.randomBytes(32); // 256-bit key
107
+
108
+ // ✅ An toàn - tạo salt cho password hashing
109
+ const saltRounds = 12;
110
+ const hashedPassword = await bcrypt.hash(password, saltRounds);
111
+
112
+ // ✅ An toàn - tạo IV cho encryption
113
+ const iv = crypto.randomBytes(16);
114
+ const cipher = crypto.createCipher('aes-256-cbc', key, iv);
115
+ ```
116
+
117
+ ### 5. Sử dụng thư viện an toàn
118
+ ```javascript
119
+ // ✅ An toàn - sử dụng nanoid
120
+ const { nanoid } = require('nanoid');
121
+ const id = nanoid(); // URL-safe, secure ID
122
+
123
+ // ✅ An toàn - sử dụng uuid v4
124
+ const { v4: uuidv4 } = require('uuid');
125
+ const userId = uuidv4();
126
+
127
+ // ✅ An toàn - sử dụng secure-random
128
+ const secureRandom = require('secure-random');
129
+ const randomBytes = secureRandom(32, { type: 'Buffer' });
130
+ ```
131
+
132
+ ### 6. Express.js session security
133
+ ```javascript
134
+ // ✅ An toàn - cấu hình Express session
135
+ const session = require('express-session');
136
+
137
+ app.use(session({
138
+ genid: () => crypto.randomUUID(), // Secure session ID
139
+ secret: crypto.randomBytes(64).toString('hex'), // Secure secret
140
+ resave: false,
141
+ saveUninitialized: false,
142
+ cookie: {
143
+ secure: true, // HTTPS only
144
+ httpOnly: true,
145
+ maxAge: 1800000 // 30 minutes
146
+ }
147
+ }));
148
+ ```
149
+
150
+ ### 7. JWT token generation
151
+ ```javascript
152
+ // ✅ An toàn - tạo JWT với secure secret
153
+ const jwtSecret = crypto.randomBytes(64).toString('hex');
154
+
155
+ const token = jwt.sign(
156
+ { userId, exp: Math.floor(Date.now() / 1000) + 3600 },
157
+ jwtSecret,
158
+ { algorithm: 'HS256' }
159
+ );
160
+ ```
161
+
162
+ ## Phương pháp phát hiện
163
+
164
+ Rule này sử dụng heuristic analysis để phát hiện:
165
+
166
+ 1. **Pattern matching**: Tìm kiếm các pattern như `Math.random()`, `Date.now()`, `performance.now()`
167
+ 2. **Context analysis**: Phân tích ngữ cảnh để xác định có phải mục đích bảo mật không
168
+ 3. **Function analysis**: Kiểm tra tên function có chứa từ khóa bảo mật
169
+ 4. **Variable analysis**: Phân tích tên biến có liên quan đến bảo mật
170
+ 5. **Surrounding context**: Kiểm tra các dòng xung quanh để xác định context
171
+
172
+ ## Cấu hình
173
+
174
+ ```json
175
+ {
176
+ "S010": {
177
+ "enabled": true,
178
+ "severity": "error",
179
+ "excludePatterns": [
180
+ "test/**",
181
+ "**/*.test.js",
182
+ "**/*.spec.js",
183
+ "**/demo/**",
184
+ "**/examples/**"
185
+ ]
186
+ }
187
+ }
188
+ ```
189
+
190
+ ## Best Practices
191
+
192
+ 1. **Luôn sử dụng CSPRNG**: Sử dụng `crypto.randomBytes()`, `crypto.randomUUID()`, `crypto.randomInt()` cho mục đích bảo mật
193
+ 2. **Đủ entropy**: Đảm bảo đủ entropy cho các giá trị random (ít nhất 128 bits cho tokens)
194
+ 3. **Secure storage**: Lưu trữ các giá trị random một cách an toàn
195
+ 4. **Time-limited**: Sử dụng expiration time cho các tokens
196
+ 5. **Proper seeding**: Đảm bảo CSPRNG được seed đúng cách
197
+ 6. **Regular rotation**: Thường xuyên rotate các keys và secrets
198
+
199
+ ## Các trường hợp ngoại lệ
200
+
201
+ Rule này sẽ KHÔNG báo lỗi trong các trường hợp sau:
202
+
203
+ ```javascript
204
+ // ✅ Không báo lỗi - sử dụng cho UI/animation
205
+ const animationDelay = Math.random() * 1000;
206
+ const chartColor = `hsl(${Math.random() * 360}, 50%, 50%)`;
207
+
208
+ // ✅ Không báo lỗi - game logic
209
+ const diceRoll = Math.floor(Math.random() * 6) + 1;
210
+ const enemySpawn = Math.random() < 0.3;
211
+
212
+ // ✅ Không báo lỗi - demo/test data
213
+ const mockData = Array.from({length: 10}, () => ({
214
+ value: Math.random() * 100
215
+ }));
216
+ ```
217
+
218
+ ## Tài liệu tham khảo
219
+
220
+ - [OWASP A02:2021 - Cryptographic Failures](https://owasp.org/Top10/A02_2021-Cryptographic_Failures/)
221
+ - [CWE-338: Use of Cryptographically Weak Pseudo-Random Number Generator](https://cwe.mitre.org/data/definitions/338.html)
222
+ - [Node.js Crypto Documentation](https://nodejs.org/api/crypto.html)
223
+ - [NIST Guidelines for Random Number Generation](https://csrc.nist.gov/publications/detail/sp/800-90a/rev-1/final)
224
+ - [Secure Random Number Generation Best Practices](https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html)