@eggjs/security 4.0.1 → 5.0.0-beta.17
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/README.md +46 -66
- package/README.zh-CN.md +56 -68
- package/dist/agent.d.ts +10 -0
- package/dist/agent.js +15 -0
- package/dist/app/extend/agent.d.ts +9 -0
- package/dist/app/extend/agent.js +12 -0
- package/dist/app/extend/application.d.ts +12 -0
- package/dist/app/extend/application.js +32 -0
- package/dist/app/extend/context.d.ts +61 -0
- package/dist/app/extend/context.js +191 -0
- package/dist/app/extend/helper.d.ts +24 -0
- package/dist/app/extend/helper.js +7 -0
- package/dist/app/extend/response.d.ts +39 -0
- package/dist/app/extend/response.js +70 -0
- package/dist/app/middleware/securities.d.ts +8 -0
- package/dist/app/middleware/securities.js +39 -0
- package/dist/app.d.ts +10 -0
- package/dist/app.js +24 -0
- package/dist/config/config.default.d.ts +870 -0
- package/dist/config/config.default.js +166 -0
- package/dist/config/config.local.d.ts +6 -0
- package/dist/config/config.local.js +5 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +5 -0
- package/dist/lib/extend/safe_curl.d.ts +20 -0
- package/dist/lib/extend/safe_curl.js +19 -0
- package/dist/lib/helper/cliFilter.d.ts +7 -0
- package/dist/lib/helper/cliFilter.js +18 -0
- package/dist/lib/helper/escape.d.ts +2 -0
- package/dist/lib/helper/escape.js +7 -0
- package/dist/lib/helper/escapeShellArg.d.ts +4 -0
- package/dist/lib/helper/escapeShellArg.js +7 -0
- package/dist/lib/helper/escapeShellCmd.d.ts +4 -0
- package/dist/lib/helper/escapeShellCmd.js +15 -0
- package/dist/lib/helper/index.d.ts +24 -0
- package/dist/lib/helper/index.js +25 -0
- package/dist/lib/helper/shtml.d.ts +6 -0
- package/dist/lib/helper/shtml.js +53 -0
- package/dist/lib/helper/sjs.d.ts +7 -0
- package/dist/lib/helper/sjs.js +36 -0
- package/dist/lib/helper/sjson.d.ts +4 -0
- package/dist/lib/helper/sjson.js +32 -0
- package/dist/lib/helper/spath.d.ts +7 -0
- package/dist/lib/helper/spath.js +16 -0
- package/dist/lib/helper/surl.d.ts +6 -0
- package/dist/lib/helper/surl.js +25 -0
- package/dist/lib/middlewares/csp.d.ts +7 -0
- package/dist/lib/middlewares/csp.js +46 -0
- package/dist/lib/middlewares/csrf.d.ts +7 -0
- package/dist/lib/middlewares/csrf.js +33 -0
- package/dist/lib/middlewares/dta.d.ts +6 -0
- package/dist/lib/middlewares/dta.js +13 -0
- package/dist/lib/middlewares/hsts.d.ts +7 -0
- package/dist/lib/middlewares/hsts.js +19 -0
- package/dist/lib/middlewares/index.d.ts +18 -0
- package/dist/lib/middlewares/index.js +27 -0
- package/dist/lib/middlewares/methodnoallow.d.ts +6 -0
- package/dist/lib/middlewares/methodnoallow.js +15 -0
- package/dist/lib/middlewares/noopen.d.ts +7 -0
- package/dist/lib/middlewares/noopen.js +17 -0
- package/dist/lib/middlewares/nosniff.d.ts +7 -0
- package/dist/lib/middlewares/nosniff.js +27 -0
- package/dist/lib/middlewares/referrerPolicy.d.ts +7 -0
- package/dist/lib/middlewares/referrerPolicy.js +31 -0
- package/dist/lib/middlewares/xframe.d.ts +7 -0
- package/dist/lib/middlewares/xframe.js +18 -0
- package/dist/lib/middlewares/xssProtection.d.ts +7 -0
- package/dist/lib/middlewares/xssProtection.js +17 -0
- package/dist/lib/utils.d.ts +24 -0
- package/dist/lib/utils.js +127 -0
- package/dist/types.d.ts +38 -0
- package/dist/types.js +1 -0
- package/package.json +75 -71
- package/dist/commonjs/agent.d.ts +0 -6
- package/dist/commonjs/agent.js +0 -14
- package/dist/commonjs/app/extend/agent.d.ts +0 -5
- package/dist/commonjs/app/extend/agent.js +0 -11
- package/dist/commonjs/app/extend/application.d.ts +0 -16
- package/dist/commonjs/app/extend/application.js +0 -35
- package/dist/commonjs/app/extend/context.d.ts +0 -68
- package/dist/commonjs/app/extend/context.js +0 -283
- package/dist/commonjs/app/extend/helper.d.ts +0 -12
- package/dist/commonjs/app/extend/helper.js +0 -10
- package/dist/commonjs/app/extend/response.d.ts +0 -41
- package/dist/commonjs/app/extend/response.js +0 -85
- package/dist/commonjs/app/middleware/securities.d.ts +0 -4
- package/dist/commonjs/app/middleware/securities.js +0 -55
- package/dist/commonjs/app.d.ts +0 -6
- package/dist/commonjs/app.js +0 -29
- package/dist/commonjs/config/config.default.d.ts +0 -871
- package/dist/commonjs/config/config.default.js +0 -357
- package/dist/commonjs/config/config.local.d.ts +0 -5
- package/dist/commonjs/config/config.local.js +0 -10
- package/dist/commonjs/index.d.ts +0 -1
- package/dist/commonjs/index.js +0 -4
- package/dist/commonjs/lib/extend/safe_curl.d.ts +0 -16
- package/dist/commonjs/lib/extend/safe_curl.js +0 -28
- package/dist/commonjs/lib/helper/cliFilter.d.ts +0 -4
- package/dist/commonjs/lib/helper/cliFilter.js +0 -20
- package/dist/commonjs/lib/helper/escape.d.ts +0 -2
- package/dist/commonjs/lib/helper/escape.js +0 -8
- package/dist/commonjs/lib/helper/escapeShellArg.d.ts +0 -1
- package/dist/commonjs/lib/helper/escapeShellArg.js +0 -8
- package/dist/commonjs/lib/helper/escapeShellCmd.d.ts +0 -1
- package/dist/commonjs/lib/helper/escapeShellCmd.js +0 -17
- package/dist/commonjs/lib/helper/index.d.ts +0 -21
- package/dist/commonjs/lib/helper/index.js +0 -26
- package/dist/commonjs/lib/helper/shtml.d.ts +0 -2
- package/dist/commonjs/lib/helper/shtml.js +0 -76
- package/dist/commonjs/lib/helper/sjs.d.ts +0 -4
- package/dist/commonjs/lib/helper/sjs.js +0 -52
- package/dist/commonjs/lib/helper/sjson.d.ts +0 -1
- package/dist/commonjs/lib/helper/sjson.js +0 -45
- package/dist/commonjs/lib/helper/spath.d.ts +0 -5
- package/dist/commonjs/lib/helper/spath.js +0 -28
- package/dist/commonjs/lib/helper/surl.d.ts +0 -2
- package/dist/commonjs/lib/helper/surl.js +0 -33
- package/dist/commonjs/lib/middlewares/csp.d.ts +0 -4
- package/dist/commonjs/lib/middlewares/csp.js +0 -68
- package/dist/commonjs/lib/middlewares/csrf.d.ts +0 -4
- package/dist/commonjs/lib/middlewares/csrf.js +0 -42
- package/dist/commonjs/lib/middlewares/dta.d.ts +0 -3
- package/dist/commonjs/lib/middlewares/dta.js +0 -14
- package/dist/commonjs/lib/middlewares/hsts.d.ts +0 -4
- package/dist/commonjs/lib/middlewares/hsts.js +0 -23
- package/dist/commonjs/lib/middlewares/index.d.ts +0 -13
- package/dist/commonjs/lib/middlewares/index.js +0 -28
- package/dist/commonjs/lib/middlewares/methodnoallow.d.ts +0 -3
- package/dist/commonjs/lib/middlewares/methodnoallow.js +0 -22
- package/dist/commonjs/lib/middlewares/noopen.d.ts +0 -4
- package/dist/commonjs/lib/middlewares/noopen.js +0 -17
- package/dist/commonjs/lib/middlewares/nosniff.d.ts +0 -4
- package/dist/commonjs/lib/middlewares/nosniff.js +0 -30
- package/dist/commonjs/lib/middlewares/referrerPolicy.d.ts +0 -4
- package/dist/commonjs/lib/middlewares/referrerPolicy.js +0 -36
- package/dist/commonjs/lib/middlewares/xframe.d.ts +0 -4
- package/dist/commonjs/lib/middlewares/xframe.js +0 -19
- package/dist/commonjs/lib/middlewares/xssProtection.d.ts +0 -4
- package/dist/commonjs/lib/middlewares/xssProtection.js +0 -16
- package/dist/commonjs/lib/utils.d.ts +0 -19
- package/dist/commonjs/lib/utils.js +0 -206
- package/dist/commonjs/package.json +0 -3
- package/dist/commonjs/types.d.ts +0 -10
- package/dist/commonjs/types.js +0 -5
- package/dist/esm/agent.d.ts +0 -6
- package/dist/esm/agent.js +0 -11
- package/dist/esm/app/extend/agent.d.ts +0 -5
- package/dist/esm/app/extend/agent.js +0 -8
- package/dist/esm/app/extend/application.d.ts +0 -16
- package/dist/esm/app/extend/application.js +0 -32
- package/dist/esm/app/extend/context.d.ts +0 -68
- package/dist/esm/app/extend/context.js +0 -244
- package/dist/esm/app/extend/helper.d.ts +0 -12
- package/dist/esm/app/extend/helper.js +0 -5
- package/dist/esm/app/extend/response.d.ts +0 -41
- package/dist/esm/app/extend/response.js +0 -82
- package/dist/esm/app/middleware/securities.d.ts +0 -4
- package/dist/esm/app/middleware/securities.js +0 -50
- package/dist/esm/app.d.ts +0 -6
- package/dist/esm/app.js +0 -26
- package/dist/esm/config/config.default.d.ts +0 -871
- package/dist/esm/config/config.default.js +0 -351
- package/dist/esm/config/config.local.d.ts +0 -5
- package/dist/esm/config/config.local.js +0 -8
- package/dist/esm/index.d.ts +0 -1
- package/dist/esm/index.js +0 -2
- package/dist/esm/lib/extend/safe_curl.d.ts +0 -16
- package/dist/esm/lib/extend/safe_curl.js +0 -25
- package/dist/esm/lib/helper/cliFilter.d.ts +0 -4
- package/dist/esm/lib/helper/cliFilter.js +0 -17
- package/dist/esm/lib/helper/escape.d.ts +0 -2
- package/dist/esm/lib/helper/escape.js +0 -3
- package/dist/esm/lib/helper/escapeShellArg.d.ts +0 -1
- package/dist/esm/lib/helper/escapeShellArg.js +0 -5
- package/dist/esm/lib/helper/escapeShellCmd.d.ts +0 -1
- package/dist/esm/lib/helper/escapeShellCmd.js +0 -14
- package/dist/esm/lib/helper/index.d.ts +0 -21
- package/dist/esm/lib/helper/index.js +0 -21
- package/dist/esm/lib/helper/shtml.d.ts +0 -2
- package/dist/esm/lib/helper/shtml.js +0 -70
- package/dist/esm/lib/helper/sjs.d.ts +0 -4
- package/dist/esm/lib/helper/sjs.js +0 -49
- package/dist/esm/lib/helper/sjson.d.ts +0 -1
- package/dist/esm/lib/helper/sjson.js +0 -39
- package/dist/esm/lib/helper/spath.d.ts +0 -5
- package/dist/esm/lib/helper/spath.js +0 -25
- package/dist/esm/lib/helper/surl.d.ts +0 -2
- package/dist/esm/lib/helper/surl.js +0 -30
- package/dist/esm/lib/middlewares/csp.d.ts +0 -4
- package/dist/esm/lib/middlewares/csp.js +0 -63
- package/dist/esm/lib/middlewares/csrf.d.ts +0 -4
- package/dist/esm/lib/middlewares/csrf.js +0 -37
- package/dist/esm/lib/middlewares/dta.d.ts +0 -3
- package/dist/esm/lib/middlewares/dta.js +0 -12
- package/dist/esm/lib/middlewares/hsts.d.ts +0 -4
- package/dist/esm/lib/middlewares/hsts.js +0 -21
- package/dist/esm/lib/middlewares/index.d.ts +0 -13
- package/dist/esm/lib/middlewares/index.js +0 -23
- package/dist/esm/lib/middlewares/methodnoallow.d.ts +0 -3
- package/dist/esm/lib/middlewares/methodnoallow.js +0 -20
- package/dist/esm/lib/middlewares/noopen.d.ts +0 -4
- package/dist/esm/lib/middlewares/noopen.js +0 -15
- package/dist/esm/lib/middlewares/nosniff.d.ts +0 -4
- package/dist/esm/lib/middlewares/nosniff.js +0 -28
- package/dist/esm/lib/middlewares/referrerPolicy.d.ts +0 -4
- package/dist/esm/lib/middlewares/referrerPolicy.js +0 -34
- package/dist/esm/lib/middlewares/xframe.d.ts +0 -4
- package/dist/esm/lib/middlewares/xframe.js +0 -17
- package/dist/esm/lib/middlewares/xssProtection.d.ts +0 -4
- package/dist/esm/lib/middlewares/xssProtection.js +0 -14
- package/dist/esm/lib/utils.d.ts +0 -19
- package/dist/esm/lib/utils.js +0 -194
- package/dist/esm/package.json +0 -3
- package/dist/esm/types.d.ts +0 -10
- package/dist/esm/types.js +0 -3
- package/dist/package.json +0 -4
- package/src/agent.ts +0 -14
- package/src/app/extend/agent.ts +0 -14
- package/src/app/extend/application.ts +0 -51
- package/src/app/extend/context.ts +0 -285
- package/src/app/extend/helper.ts +0 -5
- package/src/app/extend/response.ts +0 -95
- package/src/app/middleware/securities.ts +0 -63
- package/src/app.ts +0 -31
- package/src/config/config.default.ts +0 -379
- package/src/config/config.local.ts +0 -9
- package/src/index.ts +0 -1
- package/src/lib/extend/safe_curl.ts +0 -35
- package/src/lib/helper/cliFilter.ts +0 -20
- package/src/lib/helper/escape.ts +0 -3
- package/src/lib/helper/escapeShellArg.ts +0 -4
- package/src/lib/helper/escapeShellCmd.ts +0 -16
- package/src/lib/helper/index.ts +0 -21
- package/src/lib/helper/shtml.ts +0 -77
- package/src/lib/helper/sjs.ts +0 -57
- package/src/lib/helper/sjson.ts +0 -35
- package/src/lib/helper/spath.ts +0 -27
- package/src/lib/helper/surl.ts +0 -35
- package/src/lib/middlewares/csp.ts +0 -70
- package/src/lib/middlewares/csrf.ts +0 -44
- package/src/lib/middlewares/dta.ts +0 -13
- package/src/lib/middlewares/hsts.ts +0 -24
- package/src/lib/middlewares/index.ts +0 -23
- package/src/lib/middlewares/methodnoallow.ts +0 -23
- package/src/lib/middlewares/noopen.ts +0 -18
- package/src/lib/middlewares/nosniff.ts +0 -32
- package/src/lib/middlewares/referrerPolicy.ts +0 -39
- package/src/lib/middlewares/xframe.ts +0 -20
- package/src/lib/middlewares/xssProtection.ts +0 -17
- package/src/lib/utils.ts +0 -208
- package/src/types.ts +0 -16
- package/src/typings/index.d.ts +0 -4
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eggjs/security",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0-beta.17",
|
|
4
|
+
"type": "module",
|
|
4
5
|
"publishConfig": {
|
|
5
6
|
"access": "public"
|
|
6
7
|
},
|
|
@@ -9,12 +10,7 @@
|
|
|
9
10
|
"name": "security",
|
|
10
11
|
"optionalDependencies": [
|
|
11
12
|
"session"
|
|
12
|
-
]
|
|
13
|
-
"exports": {
|
|
14
|
-
"import": "./dist/esm",
|
|
15
|
-
"require": "./dist/commonjs",
|
|
16
|
-
"typescript": "./src"
|
|
17
|
-
}
|
|
13
|
+
]
|
|
18
14
|
},
|
|
19
15
|
"keywords": [
|
|
20
16
|
"egg",
|
|
@@ -24,93 +20,101 @@
|
|
|
24
20
|
],
|
|
25
21
|
"repository": {
|
|
26
22
|
"type": "git",
|
|
27
|
-
"url": "git+https://github.com/eggjs/
|
|
23
|
+
"url": "git+https://github.com/eggjs/egg.git",
|
|
24
|
+
"directory": "plugins/security"
|
|
28
25
|
},
|
|
29
26
|
"bugs": {
|
|
30
27
|
"url": "https://github.com/eggjs/egg/issues"
|
|
31
28
|
},
|
|
32
|
-
"homepage": "https://github.com/eggjs/security#readme",
|
|
29
|
+
"homepage": "https://github.com/eggjs/egg/tree/next/plugins/security#readme",
|
|
33
30
|
"author": "jtyjty99999",
|
|
34
31
|
"license": "MIT",
|
|
35
32
|
"engines": {
|
|
36
|
-
"node": ">= 18.
|
|
33
|
+
"node": ">= 22.18.0"
|
|
34
|
+
},
|
|
35
|
+
"exports": {
|
|
36
|
+
".": "./dist/index.js",
|
|
37
|
+
"./agent": "./dist/agent.js",
|
|
38
|
+
"./app": "./dist/app.js",
|
|
39
|
+
"./app/extend/agent": "./dist/app/extend/agent.js",
|
|
40
|
+
"./app/extend/application": "./dist/app/extend/application.js",
|
|
41
|
+
"./app/extend/context": "./dist/app/extend/context.js",
|
|
42
|
+
"./app/extend/helper": "./dist/app/extend/helper.js",
|
|
43
|
+
"./app/extend/response": "./dist/app/extend/response.js",
|
|
44
|
+
"./app/middleware/securities": "./dist/app/middleware/securities.js",
|
|
45
|
+
"./config/config.default": "./dist/config/config.default.js",
|
|
46
|
+
"./config/config.local": "./dist/config/config.local.js",
|
|
47
|
+
"./lib/extend/safe_curl": "./dist/lib/extend/safe_curl.js",
|
|
48
|
+
"./lib/helper": "./dist/lib/helper/index.js",
|
|
49
|
+
"./lib/helper/cliFilter": "./dist/lib/helper/cliFilter.js",
|
|
50
|
+
"./lib/helper/escape": "./dist/lib/helper/escape.js",
|
|
51
|
+
"./lib/helper/escapeShellArg": "./dist/lib/helper/escapeShellArg.js",
|
|
52
|
+
"./lib/helper/escapeShellCmd": "./dist/lib/helper/escapeShellCmd.js",
|
|
53
|
+
"./lib/helper/shtml": "./dist/lib/helper/shtml.js",
|
|
54
|
+
"./lib/helper/sjs": "./dist/lib/helper/sjs.js",
|
|
55
|
+
"./lib/helper/sjson": "./dist/lib/helper/sjson.js",
|
|
56
|
+
"./lib/helper/spath": "./dist/lib/helper/spath.js",
|
|
57
|
+
"./lib/helper/surl": "./dist/lib/helper/surl.js",
|
|
58
|
+
"./lib/middlewares": "./dist/lib/middlewares/index.js",
|
|
59
|
+
"./lib/middlewares/csp": "./dist/lib/middlewares/csp.js",
|
|
60
|
+
"./lib/middlewares/csrf": "./dist/lib/middlewares/csrf.js",
|
|
61
|
+
"./lib/middlewares/dta": "./dist/lib/middlewares/dta.js",
|
|
62
|
+
"./lib/middlewares/hsts": "./dist/lib/middlewares/hsts.js",
|
|
63
|
+
"./lib/middlewares/methodnoallow": "./dist/lib/middlewares/methodnoallow.js",
|
|
64
|
+
"./lib/middlewares/noopen": "./dist/lib/middlewares/noopen.js",
|
|
65
|
+
"./lib/middlewares/nosniff": "./dist/lib/middlewares/nosniff.js",
|
|
66
|
+
"./lib/middlewares/referrerPolicy": "./dist/lib/middlewares/referrerPolicy.js",
|
|
67
|
+
"./lib/middlewares/xframe": "./dist/lib/middlewares/xframe.js",
|
|
68
|
+
"./lib/middlewares/xssProtection": "./dist/lib/middlewares/xssProtection.js",
|
|
69
|
+
"./lib/utils": "./dist/lib/utils.js",
|
|
70
|
+
"./types": "./dist/types.js",
|
|
71
|
+
"./package.json": "./package.json"
|
|
37
72
|
},
|
|
38
73
|
"dependencies": {
|
|
39
|
-
"@eggjs/core": "^6.2.13",
|
|
40
74
|
"@eggjs/ip": "^2.1.0",
|
|
41
|
-
"csrf": "^3.0
|
|
42
|
-
"egg-path-matching": "^2.
|
|
75
|
+
"csrf": "^3.1.0",
|
|
76
|
+
"egg-path-matching": "^2.0.0",
|
|
43
77
|
"escape-html": "^1.0.3",
|
|
44
|
-
"extend": "^3.0.
|
|
78
|
+
"extend": "^3.0.2",
|
|
45
79
|
"koa-compose": "^4.1.0",
|
|
46
80
|
"matcher": "^4.0.0",
|
|
47
|
-
"nanoid": "^
|
|
48
|
-
"type-is": "^
|
|
49
|
-
"xss": "^1.0.
|
|
81
|
+
"nanoid": "^5.0.0",
|
|
82
|
+
"type-is": "^2.0.0",
|
|
83
|
+
"xss": "^1.0.15",
|
|
50
84
|
"zod": "^3.24.1"
|
|
51
85
|
},
|
|
86
|
+
"peerDependencies": {
|
|
87
|
+
"egg": "4.1.0-beta.17"
|
|
88
|
+
},
|
|
52
89
|
"devDependencies": {
|
|
53
|
-
"@arethetypeswrong/cli": "^0.17.1",
|
|
54
|
-
"@eggjs/bin": "7",
|
|
55
|
-
"@eggjs/mock": "^6.0.5",
|
|
56
|
-
"@eggjs/supertest": "^8.2.0",
|
|
57
|
-
"@eggjs/tsconfig": "1",
|
|
58
90
|
"@types/escape-html": "^1.0.4",
|
|
59
91
|
"@types/extend": "^3.0.4",
|
|
60
92
|
"@types/koa-compose": "^3.2.8",
|
|
61
|
-
"@types/mocha": "10",
|
|
62
|
-
"@types/node": "
|
|
63
|
-
"@types/type-is": "^1.6.
|
|
93
|
+
"@types/mocha": "^10.0.10",
|
|
94
|
+
"@types/node": "24.5.2",
|
|
95
|
+
"@types/type-is": "^1.6.6",
|
|
64
96
|
"beautify-benchmark": "^0.2.4",
|
|
65
97
|
"benchmark": "^2.1.4",
|
|
66
|
-
"egg": "^4.0.4",
|
|
67
98
|
"egg-view-nunjucks": "^2.3.0",
|
|
68
|
-
"eslint": "8",
|
|
69
|
-
"eslint-config-egg": "14",
|
|
70
|
-
"rimraf": "6",
|
|
71
|
-
"snap-shot-it": "^7.9.10",
|
|
72
99
|
"spy": "^1.0.0",
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
"
|
|
76
|
-
"
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
"lint": "eslint --cache src test --ext .ts",
|
|
80
|
-
"pretest": "npm run clean && npm run lint -- --fix",
|
|
81
|
-
"test": "egg-bin test",
|
|
82
|
-
"test:snapshot:update": "SNAPSHOT_UPDATE=1 egg-bin test",
|
|
83
|
-
"preci": "npm run clean && npm run lint",
|
|
84
|
-
"ci": "egg-bin cov",
|
|
85
|
-
"postci": "npm run prepublishOnly && npm run clean",
|
|
86
|
-
"clean": "rimraf dist",
|
|
87
|
-
"prepublishOnly": "tshy && tshy-after && attw --pack"
|
|
88
|
-
},
|
|
89
|
-
"type": "module",
|
|
90
|
-
"tshy": {
|
|
91
|
-
"exports": {
|
|
92
|
-
".": "./src/index.ts",
|
|
93
|
-
"./package.json": "./package.json"
|
|
94
|
-
}
|
|
95
|
-
},
|
|
96
|
-
"exports": {
|
|
97
|
-
".": {
|
|
98
|
-
"import": {
|
|
99
|
-
"types": "./dist/esm/index.d.ts",
|
|
100
|
-
"default": "./dist/esm/index.js"
|
|
101
|
-
},
|
|
102
|
-
"require": {
|
|
103
|
-
"types": "./dist/commonjs/index.d.ts",
|
|
104
|
-
"default": "./dist/commonjs/index.js"
|
|
105
|
-
}
|
|
106
|
-
},
|
|
107
|
-
"./package.json": "./package.json"
|
|
100
|
+
"tsdown": "^0.15.4",
|
|
101
|
+
"typescript": "5.9.2",
|
|
102
|
+
"vitest": "4.0.0-beta.13",
|
|
103
|
+
"@eggjs/supertest": "9.0.0-beta.17",
|
|
104
|
+
"@eggjs/mock": "7.0.0-beta.17",
|
|
105
|
+
"@eggjs/tsconfig": "3.1.0-beta.17"
|
|
108
106
|
},
|
|
109
107
|
"files": [
|
|
110
|
-
"dist"
|
|
111
|
-
"src"
|
|
108
|
+
"dist"
|
|
112
109
|
],
|
|
113
|
-
"
|
|
114
|
-
"
|
|
115
|
-
"
|
|
116
|
-
|
|
110
|
+
"main": "./dist/index.js",
|
|
111
|
+
"module": "./dist/index.js",
|
|
112
|
+
"types": "./dist/index.d.ts",
|
|
113
|
+
"scripts": {
|
|
114
|
+
"build": "tsdown",
|
|
115
|
+
"typecheck": "tsc --noEmit",
|
|
116
|
+
"lint": "oxlint --type-aware",
|
|
117
|
+
"lint:fix": "npm run lint -- --fix",
|
|
118
|
+
"test": "npm run lint:fix && vitest"
|
|
119
|
+
}
|
|
120
|
+
}
|
package/dist/commonjs/agent.d.ts
DELETED
package/dist/commonjs/agent.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const utils_js_1 = require("./lib/utils.js");
|
|
4
|
-
class AgentBoot {
|
|
5
|
-
agent;
|
|
6
|
-
constructor(agent) {
|
|
7
|
-
this.agent = agent;
|
|
8
|
-
}
|
|
9
|
-
async configWillLoad() {
|
|
10
|
-
(0, utils_js_1.preprocessConfig)(this.agent.config.security);
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
exports.default = AgentBoot;
|
|
14
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWdlbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYWdlbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFDQSw2Q0FBa0Q7QUFFbEQsTUFBcUIsU0FBUztJQUNYLEtBQUssQ0FBQztJQUV2QixZQUFZLEtBQWM7UUFDeEIsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7SUFDckIsQ0FBQztJQUVELEtBQUssQ0FBQyxjQUFjO1FBQ2xCLElBQUEsMkJBQWdCLEVBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDL0MsQ0FBQztDQUNGO0FBVkQsNEJBVUMifQ==
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { EggCore } from '@eggjs/core';
|
|
2
|
-
import { type HttpClientRequestURL, type HttpClientOptions, type HttpClientResponse } from '../../lib/extend/safe_curl.js';
|
|
3
|
-
export default class SecurityAgent extends EggCore {
|
|
4
|
-
safeCurl<T = any>(url: HttpClientRequestURL, options?: HttpClientOptions): Promise<HttpClientResponse<T>>;
|
|
5
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const core_1 = require("@eggjs/core");
|
|
4
|
-
const safe_curl_js_1 = require("../../lib/extend/safe_curl.js");
|
|
5
|
-
class SecurityAgent extends core_1.EggCore {
|
|
6
|
-
async safeCurl(url, options) {
|
|
7
|
-
return await (0, safe_curl_js_1.safeCurlForApplication)(this, url, options);
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
exports.default = SecurityAgent;
|
|
11
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWdlbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvYXBwL2V4dGVuZC9hZ2VudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHNDQUFzQztBQUN0QyxnRUFLdUM7QUFFdkMsTUFBcUIsYUFBYyxTQUFRLGNBQU87SUFDaEQsS0FBSyxDQUFDLFFBQVEsQ0FDWixHQUF5QixFQUFFLE9BQTJCO1FBQ3RELE9BQU8sTUFBTSxJQUFBLHFDQUFzQixFQUFJLElBQUksRUFBRSxHQUFHLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDN0QsQ0FBQztDQUNGO0FBTEQsZ0NBS0MifQ==
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { EggCore } from '@eggjs/core';
|
|
2
|
-
import { type HttpClientRequestURL, type HttpClientOptions, type HttpClientResponse } from '../../lib/extend/safe_curl.js';
|
|
3
|
-
export default class SecurityApplication extends EggCore {
|
|
4
|
-
injectCsrf(html: string): string;
|
|
5
|
-
injectNonce(html: string): string;
|
|
6
|
-
injectHijackingDefense(html: string): string;
|
|
7
|
-
safeCurl<T = any>(url: HttpClientRequestURL, options?: HttpClientOptions): Promise<HttpClientResponse<T>>;
|
|
8
|
-
}
|
|
9
|
-
declare module '@eggjs/core' {
|
|
10
|
-
interface EggCore {
|
|
11
|
-
injectCsrf(html: string): string;
|
|
12
|
-
injectNonce(html: string): string;
|
|
13
|
-
injectHijackingDefense(html: string): string;
|
|
14
|
-
safeCurl<T = any>(url: HttpClientRequestURL, options?: HttpClientOptions): Promise<HttpClientResponse<T>>;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const core_1 = require("@eggjs/core");
|
|
4
|
-
const safe_curl_js_1 = require("../../lib/extend/safe_curl.js");
|
|
5
|
-
const INPUT_CSRF = '\r\n<input type="hidden" name="_csrf" value="{{ctx.csrf}}" /></form>';
|
|
6
|
-
const INJECTION_DEFENSE = '<!--for injection--><!--</html>--><!--for injection-->';
|
|
7
|
-
class SecurityApplication extends core_1.EggCore {
|
|
8
|
-
injectCsrf(html) {
|
|
9
|
-
html = html.replace(/(<form.*?>)([\s\S]*?)<\/form>/gi, (_, $1, $2) => {
|
|
10
|
-
const match = $2;
|
|
11
|
-
if (match.indexOf('name="_csrf"') !== -1 || match.indexOf('name=\'_csrf\'') !== -1) {
|
|
12
|
-
return $1 + match + '</form>';
|
|
13
|
-
}
|
|
14
|
-
return $1 + match + INPUT_CSRF;
|
|
15
|
-
});
|
|
16
|
-
return html;
|
|
17
|
-
}
|
|
18
|
-
injectNonce(html) {
|
|
19
|
-
html = html.replace(/<script(.*?)>([\s\S]*?)<\/script[^>]*?>/gi, (_, $1, $2) => {
|
|
20
|
-
if (!$1.includes('nonce=')) {
|
|
21
|
-
$1 += ' nonce="{{ctx.nonce}}"';
|
|
22
|
-
}
|
|
23
|
-
return '<script' + $1 + '>' + $2 + '</script>';
|
|
24
|
-
});
|
|
25
|
-
return html;
|
|
26
|
-
}
|
|
27
|
-
injectHijackingDefense(html) {
|
|
28
|
-
return INJECTION_DEFENSE + html + INJECTION_DEFENSE;
|
|
29
|
-
}
|
|
30
|
-
async safeCurl(url, options) {
|
|
31
|
-
return await (0, safe_curl_js_1.safeCurlForApplication)(this, url, options);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
exports.default = SecurityApplication;
|
|
35
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwbGljYXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvYXBwL2V4dGVuZC9hcHBsaWNhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHNDQUFzQztBQUN0QyxnRUFLdUM7QUFFdkMsTUFBTSxVQUFVLEdBQUcsc0VBQXNFLENBQUM7QUFDMUYsTUFBTSxpQkFBaUIsR0FBRyx3REFBd0QsQ0FBQztBQUVuRixNQUFxQixtQkFBb0IsU0FBUSxjQUFPO0lBQ3RELFVBQVUsQ0FBQyxJQUFZO1FBQ3JCLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLGlDQUFpQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRTtZQUNuRSxNQUFNLEtBQUssR0FBRyxFQUFFLENBQUM7WUFDakIsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDO2dCQUNuRixPQUFPLEVBQUUsR0FBRyxLQUFLLEdBQUcsU0FBUyxDQUFDO1lBQ2hDLENBQUM7WUFDRCxPQUFPLEVBQUUsR0FBRyxLQUFLLEdBQUcsVUFBVSxDQUFDO1FBQ2pDLENBQUMsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsV0FBVyxDQUFDLElBQVk7UUFDdEIsSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsMkNBQTJDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFO1lBQzdFLElBQUksQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7Z0JBQzNCLEVBQUUsSUFBSSx3QkFBd0IsQ0FBQztZQUNqQyxDQUFDO1lBQ0QsT0FBTyxTQUFTLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsV0FBVyxDQUFDO1FBQ2pELENBQUMsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsc0JBQXNCLENBQUMsSUFBWTtRQUNqQyxPQUFPLGlCQUFpQixHQUFHLElBQUksR0FBRyxpQkFBaUIsQ0FBQztJQUN0RCxDQUFDO0lBRUQsS0FBSyxDQUFDLFFBQVEsQ0FDWixHQUF5QixFQUFFLE9BQTJCO1FBQ3RELE9BQU8sTUFBTSxJQUFBLHFDQUFzQixFQUFJLElBQUksRUFBRSxHQUFHLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDN0QsQ0FBQztDQUNGO0FBOUJELHNDQThCQyJ9
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { Context } from '@eggjs/core';
|
|
2
|
-
import type { HttpClientRequestURL, HttpClientOptions, HttpClientResponse } from '../../lib/extend/safe_curl.js';
|
|
3
|
-
import { SecurityConfig, SecurityHelperConfig } from '../../types.js';
|
|
4
|
-
declare const CSRF_SECRET: unique symbol;
|
|
5
|
-
declare const LOG_CSRF_NOTICE: unique symbol;
|
|
6
|
-
declare const INPUT_TOKEN: unique symbol;
|
|
7
|
-
declare const CSRF_REFERER_CHECK: unique symbol;
|
|
8
|
-
declare const CSRF_CTOKEN_CHECK: unique symbol;
|
|
9
|
-
export default class SecurityContext extends Context {
|
|
10
|
-
get securityOptions(): Partial<SecurityConfig>;
|
|
11
|
-
/**
|
|
12
|
-
* Check whether the specific `domain` is in / matches the whiteList or not.
|
|
13
|
-
* @param {string} domain The assigned domain.
|
|
14
|
-
* @param {Array<string>} [customWhiteList] The custom white list for domain.
|
|
15
|
-
* @return {boolean} If the domain is in / matches the whiteList, return true;
|
|
16
|
-
* otherwise false.
|
|
17
|
-
*/
|
|
18
|
-
isSafeDomain(domain: string, customWhiteList?: string[]): boolean;
|
|
19
|
-
get nonce(): string;
|
|
20
|
-
/**
|
|
21
|
-
* get csrf token, general use in template
|
|
22
|
-
* @return {String} csrf token
|
|
23
|
-
* @public
|
|
24
|
-
*/
|
|
25
|
-
get csrf(): string;
|
|
26
|
-
/**
|
|
27
|
-
* get csrf secret from session or cookie
|
|
28
|
-
* @return {String} csrf secret
|
|
29
|
-
* @private
|
|
30
|
-
*/
|
|
31
|
-
get [CSRF_SECRET](): string;
|
|
32
|
-
/**
|
|
33
|
-
* ensure csrf secret exists in session or cookie.
|
|
34
|
-
* @param {Boolean} [rotate] reset secret even if the secret exists
|
|
35
|
-
* @public
|
|
36
|
-
*/
|
|
37
|
-
ensureCsrfSecret(rotate?: boolean): void;
|
|
38
|
-
get [INPUT_TOKEN](): string;
|
|
39
|
-
/**
|
|
40
|
-
* rotate csrf secret exists in session or cookie.
|
|
41
|
-
* must rotate the secret when user login
|
|
42
|
-
* @public
|
|
43
|
-
*/
|
|
44
|
-
rotateCsrfSecret(): void;
|
|
45
|
-
/**
|
|
46
|
-
* assert csrf token/referer is present
|
|
47
|
-
* @public
|
|
48
|
-
*/
|
|
49
|
-
assertCsrf(): void;
|
|
50
|
-
[CSRF_CTOKEN_CHECK](): "missing csrf token" | "invalid csrf token" | undefined;
|
|
51
|
-
[CSRF_REFERER_CHECK](): "missing csrf referer or origin" | "invalid csrf referer or origin" | undefined;
|
|
52
|
-
[LOG_CSRF_NOTICE](msg: string): void;
|
|
53
|
-
safeCurl<T = any>(url: HttpClientRequestURL, options?: HttpClientOptions): Promise<HttpClientResponse<T>>;
|
|
54
|
-
unsafeRedirect(url: string, alt?: string): void;
|
|
55
|
-
}
|
|
56
|
-
declare module '@eggjs/core' {
|
|
57
|
-
interface Context {
|
|
58
|
-
get securityOptions(): Partial<SecurityConfig & SecurityHelperConfig>;
|
|
59
|
-
isSafeDomain(domain: string, customWhiteList?: string[]): boolean;
|
|
60
|
-
get nonce(): string;
|
|
61
|
-
get csrf(): string;
|
|
62
|
-
ensureCsrfSecret(rotate?: boolean): void;
|
|
63
|
-
rotateCsrfSecret(): void;
|
|
64
|
-
assertCsrf(): void;
|
|
65
|
-
safeCurl<T = any>(url: HttpClientRequestURL, options?: HttpClientOptions): Promise<HttpClientResponse<T>>;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
export {};
|
|
@@ -1,283 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
-
};
|
|
38
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
const node_util_1 = require("node:util");
|
|
40
|
-
const non_secure_1 = require("nanoid/non-secure");
|
|
41
|
-
const csrf_1 = __importDefault(require("csrf"));
|
|
42
|
-
const core_1 = require("@eggjs/core");
|
|
43
|
-
const utils = __importStar(require("../../lib/utils.js"));
|
|
44
|
-
const debug = (0, node_util_1.debuglog)('@eggjs/security/app/extend/context');
|
|
45
|
-
const tokens = new csrf_1.default();
|
|
46
|
-
const CSRF_SECRET = Symbol('egg-security#CSRF_SECRET');
|
|
47
|
-
const _CSRF_SECRET = Symbol('egg-security#_CSRF_SECRET');
|
|
48
|
-
const NEW_CSRF_SECRET = Symbol('egg-security#NEW_CSRF_SECRET');
|
|
49
|
-
const LOG_CSRF_NOTICE = Symbol('egg-security#LOG_CSRF_NOTICE');
|
|
50
|
-
const INPUT_TOKEN = Symbol('egg-security#INPUT_TOKEN');
|
|
51
|
-
const NONCE_CACHE = Symbol('egg-security#NONCE_CACHE');
|
|
52
|
-
const SECURITY_OPTIONS = Symbol('egg-security#SECURITY_OPTIONS');
|
|
53
|
-
const CSRF_REFERER_CHECK = Symbol('egg-security#CSRF_REFERER_CHECK');
|
|
54
|
-
const CSRF_CTOKEN_CHECK = Symbol('egg-security#CSRF_CTOKEN_CHECK');
|
|
55
|
-
function findToken(obj, keys) {
|
|
56
|
-
if (!obj)
|
|
57
|
-
return;
|
|
58
|
-
if (!keys || !keys.length)
|
|
59
|
-
return;
|
|
60
|
-
if (typeof keys === 'string')
|
|
61
|
-
return obj[keys];
|
|
62
|
-
for (const key of keys) {
|
|
63
|
-
if (obj[key])
|
|
64
|
-
return obj[key];
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
class SecurityContext extends core_1.Context {
|
|
68
|
-
get securityOptions() {
|
|
69
|
-
if (!this[SECURITY_OPTIONS]) {
|
|
70
|
-
this[SECURITY_OPTIONS] = {};
|
|
71
|
-
}
|
|
72
|
-
return this[SECURITY_OPTIONS];
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Check whether the specific `domain` is in / matches the whiteList or not.
|
|
76
|
-
* @param {string} domain The assigned domain.
|
|
77
|
-
* @param {Array<string>} [customWhiteList] The custom white list for domain.
|
|
78
|
-
* @return {boolean} If the domain is in / matches the whiteList, return true;
|
|
79
|
-
* otherwise false.
|
|
80
|
-
*/
|
|
81
|
-
isSafeDomain(domain, customWhiteList) {
|
|
82
|
-
const domainWhiteList = customWhiteList && customWhiteList.length > 0 ? customWhiteList : this.app.config.security.domainWhiteList;
|
|
83
|
-
return utils.isSafeDomain(domain, domainWhiteList);
|
|
84
|
-
}
|
|
85
|
-
// Add nonce, random characters will be OK.
|
|
86
|
-
// https://w3c.github.io/webappsec/specs/content-security-policy/#nonce_source
|
|
87
|
-
get nonce() {
|
|
88
|
-
if (!this[NONCE_CACHE]) {
|
|
89
|
-
this[NONCE_CACHE] = (0, non_secure_1.nanoid)(16);
|
|
90
|
-
}
|
|
91
|
-
return this[NONCE_CACHE];
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* get csrf token, general use in template
|
|
95
|
-
* @return {String} csrf token
|
|
96
|
-
* @public
|
|
97
|
-
*/
|
|
98
|
-
get csrf() {
|
|
99
|
-
// csrfSecret can be rotate, use NEW_CSRF_SECRET first
|
|
100
|
-
const secret = this[NEW_CSRF_SECRET] || this[CSRF_SECRET];
|
|
101
|
-
debug('get csrf token, NEW_CSRF_SECRET: %s, _CSRF_SECRET: %s', this[NEW_CSRF_SECRET], this[CSRF_SECRET]);
|
|
102
|
-
// In order to protect against BREACH attacks,
|
|
103
|
-
// the token is not simply the secret;
|
|
104
|
-
// a random salt is prepended to the secret and used to scramble it.
|
|
105
|
-
// http://breachattack.com/
|
|
106
|
-
return secret ? tokens.create(secret) : '';
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* get csrf secret from session or cookie
|
|
110
|
-
* @return {String} csrf secret
|
|
111
|
-
* @private
|
|
112
|
-
*/
|
|
113
|
-
get [CSRF_SECRET]() {
|
|
114
|
-
if (this[_CSRF_SECRET]) {
|
|
115
|
-
return this[_CSRF_SECRET];
|
|
116
|
-
}
|
|
117
|
-
let { useSession, sessionName, cookieName: cookieNames, cookieOptions, } = this.app.config.security.csrf;
|
|
118
|
-
// get secret from session or cookie
|
|
119
|
-
if (useSession) {
|
|
120
|
-
this[_CSRF_SECRET] = this.session[sessionName] || '';
|
|
121
|
-
}
|
|
122
|
-
else {
|
|
123
|
-
// cookieName support array. so we can change csrf cookie name smoothly
|
|
124
|
-
if (!Array.isArray(cookieNames)) {
|
|
125
|
-
cookieNames = [cookieNames];
|
|
126
|
-
}
|
|
127
|
-
for (const cookieName of cookieNames) {
|
|
128
|
-
this[_CSRF_SECRET] = this.cookies.get(cookieName, { signed: cookieOptions.signed }) || '';
|
|
129
|
-
if (this[_CSRF_SECRET]) {
|
|
130
|
-
break;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
return this[_CSRF_SECRET];
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* ensure csrf secret exists in session or cookie.
|
|
138
|
-
* @param {Boolean} [rotate] reset secret even if the secret exists
|
|
139
|
-
* @public
|
|
140
|
-
*/
|
|
141
|
-
ensureCsrfSecret(rotate) {
|
|
142
|
-
if (this[CSRF_SECRET] && !rotate)
|
|
143
|
-
return;
|
|
144
|
-
debug('ensure csrf secret, exists: %s, rotate; %s', this[CSRF_SECRET], rotate);
|
|
145
|
-
const secret = tokens.secretSync();
|
|
146
|
-
this[NEW_CSRF_SECRET] = secret;
|
|
147
|
-
let { useSession, sessionName, cookieDomain, cookieName: cookieNames, cookieOptions, } = this.app.config.security.csrf;
|
|
148
|
-
if (useSession) {
|
|
149
|
-
// TODO(fengmk2): need to refactor egg-session plugin to support ctx.session type define
|
|
150
|
-
this.session[sessionName] = secret;
|
|
151
|
-
}
|
|
152
|
-
else {
|
|
153
|
-
if (typeof cookieDomain === 'function') {
|
|
154
|
-
cookieDomain = cookieDomain(this);
|
|
155
|
-
}
|
|
156
|
-
const cookieOpts = {
|
|
157
|
-
domain: cookieDomain,
|
|
158
|
-
...cookieOptions,
|
|
159
|
-
};
|
|
160
|
-
// cookieName support array. so we can change csrf cookie name smoothly
|
|
161
|
-
if (!Array.isArray(cookieNames)) {
|
|
162
|
-
cookieNames = [cookieNames];
|
|
163
|
-
}
|
|
164
|
-
for (const cookieName of cookieNames) {
|
|
165
|
-
this.cookies.set(cookieName, secret, cookieOpts);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
get [INPUT_TOKEN]() {
|
|
170
|
-
const { headerName, bodyName, queryName } = this.app.config.security.csrf;
|
|
171
|
-
// try order: query, body, header
|
|
172
|
-
const token = findToken(this.request.query, queryName)
|
|
173
|
-
|| findToken(this.request.body, bodyName)
|
|
174
|
-
|| (headerName && this.request.get(headerName));
|
|
175
|
-
debug('get token: %j, secret: %j', token, this[CSRF_SECRET]);
|
|
176
|
-
return token;
|
|
177
|
-
}
|
|
178
|
-
/**
|
|
179
|
-
* rotate csrf secret exists in session or cookie.
|
|
180
|
-
* must rotate the secret when user login
|
|
181
|
-
* @public
|
|
182
|
-
*/
|
|
183
|
-
rotateCsrfSecret() {
|
|
184
|
-
if (!this[NEW_CSRF_SECRET] && this[CSRF_SECRET]) {
|
|
185
|
-
this.ensureCsrfSecret(true);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
/**
|
|
189
|
-
* assert csrf token/referer is present
|
|
190
|
-
* @public
|
|
191
|
-
*/
|
|
192
|
-
assertCsrf() {
|
|
193
|
-
if (utils.checkIfIgnore(this.app.config.security.csrf, this)) {
|
|
194
|
-
debug('%s, ignore by csrf options', this.path);
|
|
195
|
-
return;
|
|
196
|
-
}
|
|
197
|
-
const { type } = this.app.config.security.csrf;
|
|
198
|
-
let message;
|
|
199
|
-
const messages = [];
|
|
200
|
-
switch (type) {
|
|
201
|
-
case 'ctoken':
|
|
202
|
-
message = this[CSRF_CTOKEN_CHECK]();
|
|
203
|
-
if (message)
|
|
204
|
-
this.throw(403, message);
|
|
205
|
-
break;
|
|
206
|
-
case 'referer':
|
|
207
|
-
message = this[CSRF_REFERER_CHECK]();
|
|
208
|
-
if (message)
|
|
209
|
-
this.throw(403, message);
|
|
210
|
-
break;
|
|
211
|
-
case 'all':
|
|
212
|
-
message = this[CSRF_CTOKEN_CHECK]();
|
|
213
|
-
if (message)
|
|
214
|
-
this.throw(403, message);
|
|
215
|
-
message = this[CSRF_REFERER_CHECK]();
|
|
216
|
-
if (message)
|
|
217
|
-
this.throw(403, message);
|
|
218
|
-
break;
|
|
219
|
-
case 'any':
|
|
220
|
-
message = this[CSRF_CTOKEN_CHECK]();
|
|
221
|
-
if (!message)
|
|
222
|
-
return;
|
|
223
|
-
messages.push(message);
|
|
224
|
-
message = this[CSRF_REFERER_CHECK]();
|
|
225
|
-
if (!message)
|
|
226
|
-
return;
|
|
227
|
-
messages.push(message);
|
|
228
|
-
this.throw(403, `both ctoken and referer check error: ${messages.join(', ')}`);
|
|
229
|
-
break;
|
|
230
|
-
default:
|
|
231
|
-
this.throw(`invalid type ${type}`);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
[CSRF_CTOKEN_CHECK]() {
|
|
235
|
-
if (!this[CSRF_SECRET]) {
|
|
236
|
-
debug('missing csrf token');
|
|
237
|
-
this[LOG_CSRF_NOTICE]('missing csrf token');
|
|
238
|
-
return 'missing csrf token';
|
|
239
|
-
}
|
|
240
|
-
const token = this[INPUT_TOKEN];
|
|
241
|
-
// AJAX requests get csrf token from cookie, in this situation token will equal to secret
|
|
242
|
-
// synchronize form requests' token always changing to protect against BREACH attacks
|
|
243
|
-
if (token !== this[CSRF_SECRET] && !tokens.verify(this[CSRF_SECRET], token)) {
|
|
244
|
-
debug('verify secret and token error');
|
|
245
|
-
this[LOG_CSRF_NOTICE]('invalid csrf token');
|
|
246
|
-
const { rotateWhenInvalid } = this.app.config.security.csrf;
|
|
247
|
-
if (rotateWhenInvalid) {
|
|
248
|
-
this.rotateCsrfSecret();
|
|
249
|
-
}
|
|
250
|
-
return 'invalid csrf token';
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
[CSRF_REFERER_CHECK]() {
|
|
254
|
-
const { refererWhiteList } = this.app.config.security.csrf;
|
|
255
|
-
// check Origin/Referer headers
|
|
256
|
-
const referer = (this.headers.referer || this.headers.origin || '').toLowerCase();
|
|
257
|
-
if (!referer) {
|
|
258
|
-
debug('missing csrf referer or origin');
|
|
259
|
-
this[LOG_CSRF_NOTICE]('missing csrf referer or origin');
|
|
260
|
-
return 'missing csrf referer or origin';
|
|
261
|
-
}
|
|
262
|
-
const host = utils.getFromUrl(referer, 'host');
|
|
263
|
-
const domainList = refererWhiteList.concat(this.host);
|
|
264
|
-
if (!host || !utils.isSafeDomain(host, domainList)) {
|
|
265
|
-
debug('verify referer or origin error');
|
|
266
|
-
this[LOG_CSRF_NOTICE]('invalid csrf referer or origin');
|
|
267
|
-
return 'invalid csrf referer or origin';
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
[LOG_CSRF_NOTICE](msg) {
|
|
271
|
-
if (this.app.config.env === 'local') {
|
|
272
|
-
this.logger.warn(`${msg}. See https://eggjs.org/zh-cn/core/security.html#安全威胁csrf的防范`);
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
async safeCurl(url, options) {
|
|
276
|
-
return await this.app.safeCurl(url, options);
|
|
277
|
-
}
|
|
278
|
-
unsafeRedirect(url, alt) {
|
|
279
|
-
this.response.unsafeRedirect(url, alt);
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
exports.default = SecurityContext;
|
|
283
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGV4dC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9hcHAvZXh0ZW5kL2NvbnRleHQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSx5Q0FBcUM7QUFDckMsa0RBQTJDO0FBQzNDLGdEQUEwQjtBQUMxQixzQ0FBc0M7QUFDdEMsMERBQTRDO0FBUTVDLE1BQU0sS0FBSyxHQUFHLElBQUEsb0JBQVEsRUFBQyxvQ0FBb0MsQ0FBQyxDQUFDO0FBRTdELE1BQU0sTUFBTSxHQUFHLElBQUksY0FBTSxFQUFFLENBQUM7QUFFNUIsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLDBCQUEwQixDQUFDLENBQUM7QUFDdkQsTUFBTSxZQUFZLEdBQUcsTUFBTSxDQUFDLDJCQUEyQixDQUFDLENBQUM7QUFDekQsTUFBTSxlQUFlLEdBQUcsTUFBTSxDQUFDLDhCQUE4QixDQUFDLENBQUM7QUFDL0QsTUFBTSxlQUFlLEdBQUcsTUFBTSxDQUFDLDhCQUE4QixDQUFDLENBQUM7QUFDL0QsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLDBCQUEwQixDQUFDLENBQUM7QUFDdkQsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLDBCQUEwQixDQUFDLENBQUM7QUFDdkQsTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLENBQUMsK0JBQStCLENBQUMsQ0FBQztBQUNqRSxNQUFNLGtCQUFrQixHQUFHLE1BQU0sQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO0FBQ3JFLE1BQU0saUJBQWlCLEdBQUcsTUFBTSxDQUFDLGdDQUFnQyxDQUFDLENBQUM7QUFFbkUsU0FBUyxTQUFTLENBQUMsR0FBMkIsRUFBRSxJQUF1QjtJQUNyRSxJQUFJLENBQUMsR0FBRztRQUFFLE9BQU87SUFDakIsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNO1FBQUUsT0FBTztJQUNsQyxJQUFJLE9BQU8s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
|