chanjs 2.0.17 → 2.0.19
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/config/code.js +6 -2
- package/core/controller.js +5 -1
- package/core/service.js +161 -118
- package/extend/art-template.js +1 -1
- package/global/import.js +5 -6
- package/helper/data-parse.js +63 -46
- package/helper/db.js +16 -13
- package/helper/file.js +33 -33
- package/helper/html.js +29 -21
- package/helper/index.js +4 -8
- package/helper/ip.js +18 -17
- package/helper/jwt.js +15 -16
- package/helper/loader.js +46 -6
- package/helper/time.js +49 -3
- package/index.js +7 -5
- package/middleware/cookie.js +2 -2
- package/middleware/cors.js +3 -3
- package/middleware/header.js +1 -1
- package/middleware/index.js +21 -21
- package/middleware/setBody.js +2 -3
- package/middleware/template.js +4 -4
- package/middleware/validator.js +2 -2
- package/middleware/waf.js +133 -25
- package/package.json +1 -1
- package/utils/response.js +23 -5
package/middleware/index.js
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import {log} from "./log.js";
|
|
2
|
-
import {setCookie} from "./cookie.js";
|
|
3
|
-
import {setFavicon} from "./favicon.js";
|
|
4
|
-
import {setBody} from "./setBody.js";
|
|
5
|
-
import {setStatic} from "./static.js";
|
|
6
|
-
import {setHeader} from "./header.js";
|
|
7
|
-
import {setTemplate} from "./template.js";
|
|
8
|
-
import {validator} from "./validator.js";
|
|
9
|
-
import {Cors} from "./cors.js";
|
|
10
|
-
import {waf} from "./waf.js";
|
|
1
|
+
import { log } from "./log.js";
|
|
2
|
+
import { setCookie } from "./cookie.js";
|
|
3
|
+
import { setFavicon } from "./favicon.js";
|
|
4
|
+
import { setBody } from "./setBody.js";
|
|
5
|
+
import { setStatic } from "./static.js";
|
|
6
|
+
import { setHeader } from "./header.js";
|
|
7
|
+
import { setTemplate } from "./template.js";
|
|
8
|
+
import { validator } from "./validator.js";
|
|
9
|
+
import { Cors } from "./cors.js";
|
|
10
|
+
import { waf } from "./waf.js";
|
|
11
11
|
|
|
12
12
|
export {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
13
|
+
log,
|
|
14
|
+
setCookie,
|
|
15
|
+
setFavicon,
|
|
16
|
+
setBody,
|
|
17
|
+
setStatic,
|
|
18
|
+
setHeader,
|
|
19
|
+
setTemplate,
|
|
20
|
+
Cors,
|
|
21
|
+
validator,
|
|
22
|
+
waf,
|
|
23
|
+
};
|
package/middleware/setBody.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import express from "express";
|
|
2
|
-
|
|
3
2
|
let setBody = function (app, JSON_LIMIT) {
|
|
4
3
|
// 1. 优先解析 XML 数据(必须在 json/urlencoded 之前)
|
|
5
|
-
app.use(express.raw({ type:
|
|
4
|
+
app.use(express.raw({ type: "application/xml", limit: JSON_LIMIT }));
|
|
6
5
|
// 2. 再解析 JSON 和表单数据
|
|
7
6
|
app.use(express.json({ limit: JSON_LIMIT }));
|
|
8
7
|
app.use(express.urlencoded({ extended: false }));
|
|
9
8
|
};
|
|
10
9
|
|
|
11
|
-
export { setBody };
|
|
10
|
+
export { setBody };
|
package/middleware/template.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import "../extend/art-template.js";
|
|
2
2
|
export let setTemplate = (app, config) => {
|
|
3
|
-
const {
|
|
4
|
-
|
|
5
|
-
const all = [...views,
|
|
3
|
+
const { views, env } = config;
|
|
4
|
+
//合并插件中的view
|
|
5
|
+
const all = [...views, "app/modules/web/view"];
|
|
6
6
|
app.set("view options", {
|
|
7
7
|
debug: env === "dev",
|
|
8
8
|
cache: env === "prd",
|
package/middleware/validator.js
CHANGED
|
@@ -4,12 +4,12 @@ export const validator = (schemas) => (req, res, next) => {
|
|
|
4
4
|
headers: schemas.headers,
|
|
5
5
|
params: schemas.params,
|
|
6
6
|
query: schemas.query,
|
|
7
|
-
body: schemas.body
|
|
7
|
+
body: schemas.body,
|
|
8
8
|
};
|
|
9
9
|
|
|
10
10
|
for (const [key, schema] of Object.entries(sections)) {
|
|
11
11
|
if (!schema) continue;
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
const result = schema.safeParse(req[key]);
|
|
14
14
|
if (!result.success) {
|
|
15
15
|
// 返回首个错误信息
|
package/middleware/waf.js
CHANGED
|
@@ -6,47 +6,154 @@ const keywords = {
|
|
|
6
6
|
// 需要全词匹配的关键词(避免短词误报)
|
|
7
7
|
wholeWord: [
|
|
8
8
|
// 系统命令/工具(容易产生短词误报)
|
|
9
|
-
"opt",
|
|
10
|
-
"
|
|
9
|
+
"opt",
|
|
10
|
+
"cmd",
|
|
11
|
+
"rm",
|
|
12
|
+
"mdc",
|
|
13
|
+
"netcat",
|
|
14
|
+
"nc",
|
|
15
|
+
"mdb",
|
|
16
|
+
"bin",
|
|
17
|
+
"mk",
|
|
18
|
+
"sys",
|
|
19
|
+
"sh",
|
|
20
|
+
"chomd",
|
|
21
|
+
"php-cgi",
|
|
22
|
+
"process",
|
|
23
|
+
"require",
|
|
24
|
+
"child_process",
|
|
25
|
+
"execSync",
|
|
26
|
+
"mainModule",
|
|
11
27
|
],
|
|
12
|
-
|
|
28
|
+
|
|
13
29
|
// 普通关键词(包含特殊字符或较长关键词)
|
|
14
30
|
normal: [
|
|
15
31
|
// 文件扩展名 & 敏感文件
|
|
16
|
-
".php",
|
|
17
|
-
".
|
|
18
|
-
".
|
|
19
|
-
".
|
|
20
|
-
".
|
|
21
|
-
".
|
|
32
|
+
".php",
|
|
33
|
+
".asp",
|
|
34
|
+
".aspx",
|
|
35
|
+
".jsp",
|
|
36
|
+
".jspx",
|
|
37
|
+
".do",
|
|
38
|
+
".action",
|
|
39
|
+
".cgi",
|
|
40
|
+
".py",
|
|
41
|
+
".pl",
|
|
42
|
+
".md",
|
|
43
|
+
".log",
|
|
44
|
+
".conf",
|
|
45
|
+
".config",
|
|
46
|
+
".env",
|
|
47
|
+
".jsa",
|
|
48
|
+
".go",
|
|
49
|
+
".jhtml",
|
|
50
|
+
".shtml",
|
|
51
|
+
".cfm",
|
|
52
|
+
".svn",
|
|
53
|
+
".keys",
|
|
54
|
+
".hidden",
|
|
55
|
+
".bod",
|
|
56
|
+
".ll",
|
|
57
|
+
".backup",
|
|
58
|
+
".json",
|
|
59
|
+
".xml",
|
|
60
|
+
".bak",
|
|
61
|
+
".aws",
|
|
62
|
+
".database",
|
|
63
|
+
".cookie",
|
|
64
|
+
".rsp",
|
|
65
|
+
".old",
|
|
66
|
+
".tf",
|
|
67
|
+
".sql",
|
|
68
|
+
".vscode",
|
|
69
|
+
".docker",
|
|
70
|
+
".map",
|
|
71
|
+
".save",
|
|
72
|
+
".gz",
|
|
73
|
+
".yml",
|
|
74
|
+
".tar",
|
|
75
|
+
".sh",
|
|
76
|
+
".idea",
|
|
77
|
+
".s3",
|
|
22
78
|
|
|
23
79
|
// 敏感目录
|
|
24
|
-
"/administrator",
|
|
80
|
+
"/administrator",
|
|
81
|
+
"/wp-admin",
|
|
25
82
|
|
|
26
83
|
// 高危路径/应用
|
|
27
|
-
"phpMyAdmin",
|
|
28
|
-
"
|
|
84
|
+
"phpMyAdmin",
|
|
85
|
+
"setup",
|
|
86
|
+
"wp-",
|
|
87
|
+
"cgi-bin",
|
|
88
|
+
"xampp",
|
|
89
|
+
"staging",
|
|
90
|
+
"internal",
|
|
91
|
+
"debug",
|
|
92
|
+
"metadata",
|
|
93
|
+
"secret",
|
|
94
|
+
"smtp",
|
|
95
|
+
"redirect",
|
|
96
|
+
"configs",
|
|
29
97
|
|
|
30
98
|
// SQL 注入
|
|
31
|
-
"sleep(",
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
99
|
+
"sleep(",
|
|
100
|
+
"benchmark(",
|
|
101
|
+
"concat(",
|
|
102
|
+
"extractvalue(",
|
|
103
|
+
"updatexml(",
|
|
104
|
+
"version(",
|
|
105
|
+
"union select",
|
|
106
|
+
"union all",
|
|
107
|
+
"select @@",
|
|
108
|
+
"drop",
|
|
109
|
+
"alter",
|
|
110
|
+
"truncate",
|
|
111
|
+
"exec",
|
|
112
|
+
"(select",
|
|
113
|
+
"information_schema",
|
|
114
|
+
"load_file(",
|
|
115
|
+
"into outfile",
|
|
116
|
+
"into dumpfile",
|
|
35
117
|
|
|
36
118
|
// 命令注入
|
|
37
|
-
"cmd=",
|
|
38
|
-
"
|
|
39
|
-
"
|
|
119
|
+
"cmd=",
|
|
120
|
+
"system(",
|
|
121
|
+
"exec(",
|
|
122
|
+
"shell_exec(",
|
|
123
|
+
"passthru(",
|
|
124
|
+
"base64_decode",
|
|
125
|
+
"eval(",
|
|
126
|
+
"assert(",
|
|
127
|
+
"preg_replace",
|
|
128
|
+
"bash -i",
|
|
129
|
+
"rm -rf",
|
|
130
|
+
"wget ",
|
|
131
|
+
"curl ",
|
|
132
|
+
"chmod ",
|
|
133
|
+
"phpinfo()",
|
|
40
134
|
|
|
41
135
|
// 路径遍历
|
|
42
|
-
"../",
|
|
136
|
+
"../",
|
|
137
|
+
"..\\",
|
|
138
|
+
"/etc/passwd",
|
|
139
|
+
"/etc/shadow",
|
|
43
140
|
|
|
44
141
|
// XSS
|
|
45
|
-
"<script",
|
|
142
|
+
"<script",
|
|
143
|
+
"javascript:",
|
|
144
|
+
"onerror=",
|
|
145
|
+
"onload=",
|
|
146
|
+
"alert(",
|
|
147
|
+
"document.cookie",
|
|
46
148
|
|
|
47
149
|
// 特殊编码
|
|
48
|
-
"0x7e",
|
|
49
|
-
|
|
150
|
+
"0x7e",
|
|
151
|
+
"UNION%20SELECT",
|
|
152
|
+
"%27OR%27",
|
|
153
|
+
"{{",
|
|
154
|
+
"}}",
|
|
155
|
+
"1+1",
|
|
156
|
+
],
|
|
50
157
|
};
|
|
51
158
|
|
|
52
159
|
// === 预处理:构建正则缓存 ===
|
|
@@ -116,7 +223,7 @@ const safe = (req, res, next) => {
|
|
|
116
223
|
}
|
|
117
224
|
|
|
118
225
|
const fullText = checkText + bodyText;
|
|
119
|
-
|
|
226
|
+
|
|
120
227
|
// 空文本直接跳过检测
|
|
121
228
|
if (!fullText.trim()) return next();
|
|
122
229
|
|
|
@@ -151,7 +258,8 @@ const safe = (req, res, next) => {
|
|
|
151
258
|
userAgent: userAgent.substring(0, 100),
|
|
152
259
|
method: req.method,
|
|
153
260
|
matchedKeyword,
|
|
154
|
-
sample:
|
|
261
|
+
sample:
|
|
262
|
+
fullText.substring(0, 200) + (fullText.length > 200 ? "..." : ""),
|
|
155
263
|
});
|
|
156
264
|
|
|
157
265
|
// 根据WAF级别决定拦截方式
|
package/package.json
CHANGED
package/utils/response.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { CODE, DB_ERROR } from "../config/code.js";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
/**
|
|
4
|
+
* @description 获取数据库错误码
|
|
5
|
+
* @param {*} error
|
|
6
|
+
* @returns {Number} 默认错误码
|
|
7
|
+
*/
|
|
8
|
+
const getDefaultErrorCode = (error) => {
|
|
5
9
|
if (error.message.includes("syntax") || error.message.includes("SQL")) {
|
|
6
10
|
return 6008;
|
|
7
11
|
} else if (error.message.includes("Connection closed")) {
|
|
@@ -12,11 +16,14 @@ export const getDefaultErrorCode = (error) => {
|
|
|
12
16
|
return 5001;
|
|
13
17
|
};
|
|
14
18
|
|
|
19
|
+
/**
|
|
20
|
+
* @description 数据库错误响应处理函数
|
|
21
|
+
* @param {*} err
|
|
22
|
+
* @returns {Object} 错误响应对象
|
|
23
|
+
*/
|
|
15
24
|
export const error = (err) => {
|
|
16
25
|
console.error("DB Error:", err);
|
|
17
|
-
// 从映射表获取状态码或使用默认错误码
|
|
18
26
|
const errorCode = DB_ERROR[err.code] || getDefaultErrorCode(err);
|
|
19
|
-
|
|
20
27
|
return {
|
|
21
28
|
success: false,
|
|
22
29
|
msg: CODE[errorCode], // 从CODE对象获取错误消息
|
|
@@ -28,8 +35,13 @@ export const error = (err) => {
|
|
|
28
35
|
};
|
|
29
36
|
};
|
|
30
37
|
|
|
38
|
+
/**
|
|
39
|
+
* @description 错误响应处理函数
|
|
40
|
+
* @param {*} msg
|
|
41
|
+
* @param {*} data
|
|
42
|
+
* @returns {Object} 失败响应对象
|
|
43
|
+
*/
|
|
31
44
|
export const fail = (msg = CODE[201], data = {}) => {
|
|
32
|
-
console.warn("Operation failed:", msg);
|
|
33
45
|
return {
|
|
34
46
|
success: false,
|
|
35
47
|
msg,
|
|
@@ -38,6 +50,12 @@ export const fail = (msg = CODE[201], data = {}) => {
|
|
|
38
50
|
};
|
|
39
51
|
};
|
|
40
52
|
|
|
53
|
+
/**
|
|
54
|
+
* @description 成功响应处理函数
|
|
55
|
+
* @param {*} data
|
|
56
|
+
* @param {*} msg
|
|
57
|
+
* @returns {Object} 成功响应对象
|
|
58
|
+
*/
|
|
41
59
|
export const success = (data = {}, msg = CODE[200]) => ({
|
|
42
60
|
success: true,
|
|
43
61
|
msg,
|