mm_os 3.2.9 → 3.3.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.
Files changed (38) hide show
  1. package/README.md +47 -1
  2. package/core/base/mqtt/index.js +10 -10
  3. package/core/base/web/index.js +98 -11
  4. package/core/com/middleware/com.js +152 -152
  5. package/core/com/socket/config.tpl.json +2 -2
  6. package/core/com/socket/drive.js +2 -2
  7. package/core/com/socket/index.js +1 -1
  8. package/core/com/sql/drive.js +7 -7
  9. package/index.js +40 -30
  10. package/middleware/performance/index.js +150 -142
  11. package/middleware/security_audit/index.js +549 -0
  12. package/middleware/security_audit/middleware.json +48 -0
  13. package/middleware/security_headers/index.js +487 -0
  14. package/middleware/security_headers/middleware.json +45 -0
  15. package/middleware/waf/index.js +277 -6
  16. package/middleware/waf/middleware.json +2 -1
  17. package/middleware/waf_ddos/index.js +520 -0
  18. package/middleware/waf_ddos/middleware.json +38 -0
  19. package/middleware/waf_ip/index.js +231 -20
  20. package/middleware/waf_ip/middleware.json +43 -4
  21. package/middleware/waf_xss/index.js +269 -0
  22. package/middleware/waf_xss/middleware.json +18 -0
  23. package/middleware/web_before/middleware.json +1 -1
  24. package/middleware/web_socket/middleware.json +2 -2
  25. package/package.json +18 -7
  26. package/middleware/cors/index.js +0 -103
  27. package/middleware/cors/middleware.json +0 -9
  28. package/middleware/log/index.js +0 -32
  29. package/middleware/log/middleware.json +0 -9
  30. package/middleware/rate_limit/index.js +0 -112
  31. package/middleware/rate_limit/middleware.json +0 -10
  32. package/nodemon.json +0 -31
  33. package/package.txt +0 -1
  34. package/rps.bat +0 -3
  35. package/test.js +0 -10
  36. package/tps.bat +0 -3
  37. package/update.bat +0 -1
  38. package//347/263/273/347/273/237/346/236/266/346/236/204/350/257/204/344/274/260/344/270/216/344/274/230/345/214/226/345/273/272/350/256/256.md +0 -599
@@ -23,7 +23,20 @@ function waf_check(url) {
23
23
  /\<(iframe|script|body|img|layer|div|meta|style|base|object|input)/i,
24
24
  /(onmouseover|onmousemove|onerror|onload)\=/i,
25
25
  /javascript:/i,
26
- /\.\.\/\.\.\//i,
26
+ // 增强的路径遍历检测规则
27
+ /\.\.\//i, // 基础 ../
28
+ /\.\.\\/i, // Windows格式 ..\
29
+ /\%2e\%2e\//i, // URL编码 ../
30
+ /\%2e%2e\//i, // URL编码 ../
31
+ /\%252e%252e%2f/i, // 双重URL编码 ../
32
+ /\%252e\%252e\%2f/i, // 双重URL编码 ../
33
+ /\.\%2e\//i, // 混合编码
34
+ /\%2e\./i, // 变体形式
35
+ /\%5c/i, // 反斜杠URL编码
36
+ /\%255c/i, // 反斜杠双重URL编码
37
+ // 系统文件路径检测
38
+ /(?:\/etc|\/proc|\/sys|\/dev|C:\\Windows|C:\\winnt|C:\\Program Files)/i,
39
+ // 命令注入检测
27
40
  /\|\|.*(?:ls|pwd|whoami|ll|ifconfog|ipconfig|&&|chmod|cd|mkdir|rmdir|cp|mv)/i,
28
41
  /(?:ls|pwd|whoami|ll|ifconfog|ipconfig|&&|chmod|cd|mkdir|rmdir|cp|mv).*\|\|/i,
29
42
  /(gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\:\//i
@@ -36,6 +49,98 @@ function waf_check(url) {
36
49
  return null;
37
50
  }
38
51
 
52
+ /**
53
+ * 检查路径是否包含路径遍历攻击
54
+ * @param {String} path 路径
55
+ * @returns {Boolean} 是否包含路径遍历
56
+ */
57
+ function checkPathTraversal(path) {
58
+ // 规范化路径以处理各种编码
59
+ let normalizedPath = path;
60
+
61
+ // 处理URL编码变体
62
+ const urlDecoded = decodeURIComponent(path);
63
+ const doubleUrlDecoded = decodeURIComponent(urlDecoded);
64
+
65
+ // 检查路径是否包含危险模式
66
+ const dangerousPatterns = [
67
+ '../', '../../', '../../../', // Unix/Linux格式
68
+ '..\\', '..\\\\', '..\\\\\\', // Windows格式
69
+ '/%2e%2e/', '/%2e%2e%2f', // URL编码变体
70
+ '\\%2e%2e\\', '\\%2e%2e\\\\' // Windows URL编码变体
71
+ ];
72
+
73
+ // 检查系统关键文件路径(绝对路径攻击)
74
+ const systemPaths = [
75
+ '/etc/passwd', '/etc/shadow', '/etc/group', '/etc/hosts',
76
+ '/proc/', '/sys/', '/dev/', '/bin/', '/usr/bin/',
77
+ 'C:\\Windows\\', 'C:\\winnt\\', 'C:\\Program Files\\'
78
+ ];
79
+
80
+ // 检查原始路径、单次解码和双重解码后的路径
81
+ // 1. 检查相对路径遍历模式
82
+ const hasTraversalPattern = dangerousPatterns.some(pattern =>
83
+ path.includes(pattern) ||
84
+ urlDecoded.includes(pattern) ||
85
+ doubleUrlDecoded.includes(pattern)
86
+ );
87
+
88
+ // 2. 检查绝对路径攻击(包含系统关键文件路径)
89
+ const hasAbsoluteAttack = systemPaths.some(systemPath =>
90
+ path.toLowerCase().includes(systemPath.toLowerCase()) ||
91
+ urlDecoded.toLowerCase().includes(systemPath.toLowerCase()) ||
92
+ doubleUrlDecoded.toLowerCase().includes(systemPath.toLowerCase())
93
+ );
94
+
95
+ // 3. 检查是否以/开头的绝对路径(排除正常的网站路径)
96
+ const startsWithSlash = path.startsWith('/') &&
97
+ !path.startsWith('/api') &&
98
+ !path.startsWith('/static') &&
99
+ !path.startsWith('/public') &&
100
+ !path.startsWith('/assets') &&
101
+ !path.startsWith('/favicon.ico') &&
102
+ !path.startsWith('/robots.txt');
103
+
104
+ // 4. 检查是否包含敏感的系统文件扩展名
105
+ const hasSensitiveExtension = /\.(conf|ini|log|env|git|svn|htpasswd|htaccess|bashrc|bash_history|ssh|key|pem|cer|crt|pfx|p12)$/i.test(path) ||
106
+ /\.(conf|ini|log|env|git|svn|htpasswd|htaccess|bashrc|bash_history|ssh|key|pem|cer|crt|pfx|p12)$/i.test(urlDecoded) ||
107
+ /\.(conf|ini|log|env|git|svn|htpasswd|htaccess|bashrc|bash_history|ssh|key|pem|cer|crt|pfx|p12)$/i.test(doubleUrlDecoded);
108
+
109
+ return hasTraversalPattern || hasAbsoluteAttack || startsWithSlash || hasSensitiveExtension;
110
+ }
111
+
112
+ /**
113
+ * 检查请求路径是否规范化,防止路径遍历攻击
114
+ * @param {String} path 请求路径
115
+ * @returns {Boolean} 是否为安全路径
116
+ */
117
+ function isSafePath(path) {
118
+ // 特殊处理根路径,直接返回安全
119
+ if (path === '/') {
120
+ return true;
121
+ }
122
+
123
+ // 获取规范化的路径
124
+ const normalizedPath = path.split('/')
125
+ .filter(segment => segment !== '')
126
+ .reduce((acc, segment) => {
127
+ // 防止路径回溯
128
+ if (segment === '..') {
129
+ acc.pop();
130
+ } else if (segment !== '.') {
131
+ acc.push(segment);
132
+ }
133
+ return acc;
134
+ }, [])
135
+ .join('/');
136
+
137
+ // 重新构建规范化的完整路径
138
+ const safePath = '/' + normalizedPath;
139
+
140
+ // 检查规范化后的路径长度是否小于原始路径(表示存在路径回溯)
141
+ return safePath.length >= path.length - 2; // 允许末尾的 '/' 差异
142
+ }
143
+
39
144
  function getClientIP(req) {
40
145
  return req.headers['x-forwarded-for'] || req.headers['X-Forwarded-For'] ||
41
146
  req.connection.remoteAddress ||
@@ -43,20 +148,131 @@ function getClientIP(req) {
43
148
  req.connection.socket.remoteAddress;
44
149
  };
45
150
 
151
+ /**
152
+ * 检查IP是否在白名单中
153
+ * @param {String} ip IP地址
154
+ * @param {Object} config WAF配置
155
+ * @returns {Boolean} 是否在白名单中
156
+ */
157
+ function isInWhitelist(ip, config) {
158
+ // 获取配置中的白名单,如果不存在则使用默认白名单
159
+ const whitelist = config && config.ip_whitelist && Array.isArray(config.ip_whitelist)
160
+ ? config.ip_whitelist
161
+ : ['127.0.0.1', '::1', 'localhost', '192.168.31.5'];
162
+
163
+ return whitelist.includes(ip);
164
+ }
165
+
166
+ /**
167
+ * 检查路径是否在白名单中
168
+ * @param {String} path 请求路径
169
+ * @param {Object} config WAF配置
170
+ * @returns {Boolean} 是否在白名单中
171
+ */
172
+ function isPathWhitelisted(path, config) {
173
+ // 获取配置中的路径白名单,如果不存在则使用默认路径白名单
174
+ const pathWhitelist = config && config.path_whitelist && Array.isArray(config.path_whitelist)
175
+ ? config.path_whitelist
176
+ : ['/static', '/favicon.ico', '/api', '/public', '/assets'];
177
+
178
+ // 检查路径是否以白名单中的任何路径开头
179
+ return pathWhitelist.some(whitelistPath => path.startsWith(whitelistPath));
180
+ }
181
+
46
182
  /**
47
183
  * web防火墙
48
184
  * @param {Object} server 服务
49
185
  * @param {Object} config 配置参数
50
186
  */
51
187
  module.exports = function(server, config) {
188
+ // 设置默认配置
189
+ const defaultConfig = {
190
+ log: true,
191
+ ip_whitelist: ['127.0.0.1', '::1', 'localhost', '192.168.31.5'],
192
+ path_whitelist: ['/static', '/favicon.ico', '/api', '/public', '/assets']
193
+ };
194
+
195
+ // 强制输出初始化日志
196
+ console.log('WAF MIDDLEWARE INITIALIZED');
197
+
198
+ // 获取全局配置中的middleware.waf配置
199
+ let wafConfig = defaultConfig;
200
+ try {
201
+ // 尝试从全局配置中获取middleware.waf配置
202
+ const fs = require('fs');
203
+ const path = require('path');
204
+ const configPath = path.resolve(process.cwd(), 'config.json');
205
+ if (fs.existsSync(configPath)) {
206
+ const globalConfig = JSON.parse(fs.readFileSync(configPath, 'utf8'));
207
+ if (globalConfig.middleware && globalConfig.middleware.waf) {
208
+ // 安全地合并默认配置和全局配置
209
+ wafConfig = Object.assign({}, defaultConfig, globalConfig.middleware.waf);
210
+ console.log('WAF using global config from config.json');
211
+ } else {
212
+ console.log('WAF using default config (no middleware.waf in config.json)');
213
+ }
214
+ }
215
+ } catch (error) {
216
+ console.error('Error loading global WAF config:', error.message);
217
+ // 出错时使用默认配置
218
+ wafConfig = defaultConfig;
219
+ }
220
+
221
+ // 确保白名单数组存在且为数组类型
222
+ if (!Array.isArray(wafConfig.ip_whitelist)) {
223
+ wafConfig.ip_whitelist = defaultConfig.ip_whitelist;
224
+ }
225
+ if (!Array.isArray(wafConfig.path_whitelist)) {
226
+ wafConfig.path_whitelist = defaultConfig.path_whitelist;
227
+ }
228
+
229
+ // 合并传入的config和全局配置
230
+ const mergedConfig = { ...wafConfig, ...(config || {}) };
231
+ console.log('Merged WAF Config:', JSON.stringify(mergedConfig));
232
+
52
233
  /* WAF(web防火墙) */
53
234
  server.use(async (ctx, next) => {
54
235
  try {
236
+ // 获取客户端IP
237
+ var ip = getClientIP(ctx.req);
238
+ // 规范化IP格式,移除IPv6前缀
239
+ if (ip && ip.startsWith('::ffff:')) {
240
+ ip = ip.substring(7);
241
+ }
242
+
243
+ // 获取请求路径
244
+ const path = ctx.path;
245
+
246
+ // 强制输出请求处理日志
247
+ console.log('WAF PROCESSING REQUEST');
248
+ console.log('URL:', ctx.url);
249
+ console.log('Path:', path);
250
+ console.log('Method:', ctx.method);
251
+ console.log('IP:', ip);
252
+
253
+ // 检查IP是否在白名单中,如果是则跳过所有检查
254
+ if (isInWhitelist(ip, mergedConfig)) {
255
+ console.log(`WAF: IP ${ip} in whitelist, skipping checks`);
256
+ await next();
257
+ return;
258
+ }
259
+
260
+ // 检查路径是否在白名单中
261
+ if (isPathWhitelisted(path, mergedConfig)) {
262
+ console.log(`WAF: Path ${path} in whitelist, skipping checks`);
263
+ await next();
264
+ return;
265
+ }
266
+
267
+ // 获取请求路径和完整URL
55
268
  var url = ctx.url;
269
+
270
+ // 1. 使用正则表达式检查基本攻击特征
271
+ console.log('Step 1: Basic attack pattern check');
56
272
  var danger = waf_check(url);
273
+ console.log('WAF check result:', danger ? danger.toString() : 'safe');
57
274
  if (danger) {
58
- var ip = getClientIP(ctx.req);
59
- $.log.warn(`检测到来自IP ${ip} 的攻击`, "规则:", danger.toString());
275
+ console.warn(`BLOCKED ATTACK from IP ${ip}:`, danger.toString());
60
276
  // 阻止攻击请求,返回403禁止访问
61
277
  ctx.status = 403;
62
278
  ctx.body = {
@@ -64,11 +280,66 @@ module.exports = function(server, config) {
64
280
  msg: '访问被WAF阻止,请求包含潜在的攻击特征',
65
281
  rule: danger.toString()
66
282
  };
67
- } else {
68
- await next();
283
+ return;
284
+ }
285
+
286
+ // 2. 专门检查路径遍历攻击
287
+ console.log('Step 2: Path traversal check');
288
+ const hasTraversal = checkPathTraversal(path);
289
+ const isSafe = isSafePath(path);
290
+ console.log('Path traversal check results:', { path, hasTraversal, isSafe });
291
+
292
+ if (hasTraversal || !isSafe) {
293
+ console.warn(`BLOCKED PATH TRAVERSAL from IP ${ip}:`, path);
294
+ ctx.status = 403;
295
+ ctx.body = {
296
+ code: 403,
297
+ msg: '访问被WAF阻止,检测到路径遍历攻击尝试'
298
+ };
299
+ return;
300
+ }
301
+
302
+ // 3. 检查请求参数中的路径遍历
303
+ console.log('Step 3: Query parameter traversal check');
304
+ const queryParams = ctx.query;
305
+ for (const [key, value] of Object.entries(queryParams)) {
306
+ if (typeof value === 'string') {
307
+ const paramHasTraversal = checkPathTraversal(value);
308
+ console.log('Param check:', { key, value, paramHasTraversal });
309
+ if (paramHasTraversal) {
310
+ console.warn(`BLOCKED PARAM TRAVERSAL from IP ${ip}:`, `${key}=${value}`);
311
+ ctx.status = 403;
312
+ ctx.body = {
313
+ code: 403,
314
+ msg: '访问被WAF阻止,请求参数中包含路径遍历攻击尝试'
315
+ };
316
+ return;
317
+ }
318
+ }
69
319
  }
320
+
321
+ // 4. 如果是POST请求,检查请求体
322
+ console.log('Step 4: POST body traversal check');
323
+ if (ctx.method === 'POST' && ctx.request.body) {
324
+ const bodyContent = JSON.stringify(ctx.request.body);
325
+ const bodyHasTraversal = checkPathTraversal(bodyContent);
326
+ console.log('Body check results:', bodyHasTraversal);
327
+ if (bodyHasTraversal) {
328
+ console.warn(`BLOCKED BODY TRAVERSAL from IP ${ip}`);
329
+ ctx.status = 403;
330
+ ctx.body = {
331
+ code: 403,
332
+ msg: '访问被WAF阻止,请求体中包含路径遍历攻击尝试'
333
+ };
334
+ return;
335
+ }
336
+ }
337
+
338
+ console.log('WAF: All checks passed, continuing request');
339
+ // 所有检查通过,继续处理请求
340
+ await next();
70
341
  } catch (error) {
71
- $.log.error('WAF中间件错误:', error);
342
+ console.error('WAF MIDDLEWARE ERROR:', error);
72
343
  // 出错时默认允许请求继续处理
73
344
  await next();
74
345
  }
@@ -5,5 +5,6 @@
5
5
  "version": "1.0",
6
6
  "type": "web",
7
7
  "process_type": "common_before",
8
- "sort": 20
8
+ "sort": 20,
9
+ "state": 1
9
10
  }