@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.
Files changed (252) hide show
  1. package/README.md +46 -66
  2. package/README.zh-CN.md +56 -68
  3. package/dist/agent.d.ts +10 -0
  4. package/dist/agent.js +15 -0
  5. package/dist/app/extend/agent.d.ts +9 -0
  6. package/dist/app/extend/agent.js +12 -0
  7. package/dist/app/extend/application.d.ts +12 -0
  8. package/dist/app/extend/application.js +32 -0
  9. package/dist/app/extend/context.d.ts +61 -0
  10. package/dist/app/extend/context.js +191 -0
  11. package/dist/app/extend/helper.d.ts +24 -0
  12. package/dist/app/extend/helper.js +7 -0
  13. package/dist/app/extend/response.d.ts +39 -0
  14. package/dist/app/extend/response.js +70 -0
  15. package/dist/app/middleware/securities.d.ts +8 -0
  16. package/dist/app/middleware/securities.js +39 -0
  17. package/dist/app.d.ts +10 -0
  18. package/dist/app.js +24 -0
  19. package/dist/config/config.default.d.ts +870 -0
  20. package/dist/config/config.default.js +166 -0
  21. package/dist/config/config.local.d.ts +6 -0
  22. package/dist/config/config.local.js +5 -0
  23. package/dist/index.d.ts +1 -0
  24. package/dist/index.js +5 -0
  25. package/dist/lib/extend/safe_curl.d.ts +20 -0
  26. package/dist/lib/extend/safe_curl.js +19 -0
  27. package/dist/lib/helper/cliFilter.d.ts +7 -0
  28. package/dist/lib/helper/cliFilter.js +18 -0
  29. package/dist/lib/helper/escape.d.ts +2 -0
  30. package/dist/lib/helper/escape.js +7 -0
  31. package/dist/lib/helper/escapeShellArg.d.ts +4 -0
  32. package/dist/lib/helper/escapeShellArg.js +7 -0
  33. package/dist/lib/helper/escapeShellCmd.d.ts +4 -0
  34. package/dist/lib/helper/escapeShellCmd.js +15 -0
  35. package/dist/lib/helper/index.d.ts +24 -0
  36. package/dist/lib/helper/index.js +25 -0
  37. package/dist/lib/helper/shtml.d.ts +6 -0
  38. package/dist/lib/helper/shtml.js +53 -0
  39. package/dist/lib/helper/sjs.d.ts +7 -0
  40. package/dist/lib/helper/sjs.js +36 -0
  41. package/dist/lib/helper/sjson.d.ts +4 -0
  42. package/dist/lib/helper/sjson.js +32 -0
  43. package/dist/lib/helper/spath.d.ts +7 -0
  44. package/dist/lib/helper/spath.js +16 -0
  45. package/dist/lib/helper/surl.d.ts +6 -0
  46. package/dist/lib/helper/surl.js +25 -0
  47. package/dist/lib/middlewares/csp.d.ts +7 -0
  48. package/dist/lib/middlewares/csp.js +46 -0
  49. package/dist/lib/middlewares/csrf.d.ts +7 -0
  50. package/dist/lib/middlewares/csrf.js +33 -0
  51. package/dist/lib/middlewares/dta.d.ts +6 -0
  52. package/dist/lib/middlewares/dta.js +13 -0
  53. package/dist/lib/middlewares/hsts.d.ts +7 -0
  54. package/dist/lib/middlewares/hsts.js +19 -0
  55. package/dist/lib/middlewares/index.d.ts +18 -0
  56. package/dist/lib/middlewares/index.js +27 -0
  57. package/dist/lib/middlewares/methodnoallow.d.ts +6 -0
  58. package/dist/lib/middlewares/methodnoallow.js +15 -0
  59. package/dist/lib/middlewares/noopen.d.ts +7 -0
  60. package/dist/lib/middlewares/noopen.js +17 -0
  61. package/dist/lib/middlewares/nosniff.d.ts +7 -0
  62. package/dist/lib/middlewares/nosniff.js +27 -0
  63. package/dist/lib/middlewares/referrerPolicy.d.ts +7 -0
  64. package/dist/lib/middlewares/referrerPolicy.js +31 -0
  65. package/dist/lib/middlewares/xframe.d.ts +7 -0
  66. package/dist/lib/middlewares/xframe.js +18 -0
  67. package/dist/lib/middlewares/xssProtection.d.ts +7 -0
  68. package/dist/lib/middlewares/xssProtection.js +17 -0
  69. package/dist/lib/utils.d.ts +24 -0
  70. package/dist/lib/utils.js +127 -0
  71. package/dist/types.d.ts +38 -0
  72. package/dist/types.js +1 -0
  73. package/package.json +75 -71
  74. package/dist/commonjs/agent.d.ts +0 -6
  75. package/dist/commonjs/agent.js +0 -14
  76. package/dist/commonjs/app/extend/agent.d.ts +0 -5
  77. package/dist/commonjs/app/extend/agent.js +0 -11
  78. package/dist/commonjs/app/extend/application.d.ts +0 -16
  79. package/dist/commonjs/app/extend/application.js +0 -35
  80. package/dist/commonjs/app/extend/context.d.ts +0 -68
  81. package/dist/commonjs/app/extend/context.js +0 -283
  82. package/dist/commonjs/app/extend/helper.d.ts +0 -12
  83. package/dist/commonjs/app/extend/helper.js +0 -10
  84. package/dist/commonjs/app/extend/response.d.ts +0 -41
  85. package/dist/commonjs/app/extend/response.js +0 -85
  86. package/dist/commonjs/app/middleware/securities.d.ts +0 -4
  87. package/dist/commonjs/app/middleware/securities.js +0 -55
  88. package/dist/commonjs/app.d.ts +0 -6
  89. package/dist/commonjs/app.js +0 -29
  90. package/dist/commonjs/config/config.default.d.ts +0 -871
  91. package/dist/commonjs/config/config.default.js +0 -357
  92. package/dist/commonjs/config/config.local.d.ts +0 -5
  93. package/dist/commonjs/config/config.local.js +0 -10
  94. package/dist/commonjs/index.d.ts +0 -1
  95. package/dist/commonjs/index.js +0 -4
  96. package/dist/commonjs/lib/extend/safe_curl.d.ts +0 -16
  97. package/dist/commonjs/lib/extend/safe_curl.js +0 -28
  98. package/dist/commonjs/lib/helper/cliFilter.d.ts +0 -4
  99. package/dist/commonjs/lib/helper/cliFilter.js +0 -20
  100. package/dist/commonjs/lib/helper/escape.d.ts +0 -2
  101. package/dist/commonjs/lib/helper/escape.js +0 -8
  102. package/dist/commonjs/lib/helper/escapeShellArg.d.ts +0 -1
  103. package/dist/commonjs/lib/helper/escapeShellArg.js +0 -8
  104. package/dist/commonjs/lib/helper/escapeShellCmd.d.ts +0 -1
  105. package/dist/commonjs/lib/helper/escapeShellCmd.js +0 -17
  106. package/dist/commonjs/lib/helper/index.d.ts +0 -21
  107. package/dist/commonjs/lib/helper/index.js +0 -26
  108. package/dist/commonjs/lib/helper/shtml.d.ts +0 -2
  109. package/dist/commonjs/lib/helper/shtml.js +0 -76
  110. package/dist/commonjs/lib/helper/sjs.d.ts +0 -4
  111. package/dist/commonjs/lib/helper/sjs.js +0 -52
  112. package/dist/commonjs/lib/helper/sjson.d.ts +0 -1
  113. package/dist/commonjs/lib/helper/sjson.js +0 -45
  114. package/dist/commonjs/lib/helper/spath.d.ts +0 -5
  115. package/dist/commonjs/lib/helper/spath.js +0 -28
  116. package/dist/commonjs/lib/helper/surl.d.ts +0 -2
  117. package/dist/commonjs/lib/helper/surl.js +0 -33
  118. package/dist/commonjs/lib/middlewares/csp.d.ts +0 -4
  119. package/dist/commonjs/lib/middlewares/csp.js +0 -68
  120. package/dist/commonjs/lib/middlewares/csrf.d.ts +0 -4
  121. package/dist/commonjs/lib/middlewares/csrf.js +0 -42
  122. package/dist/commonjs/lib/middlewares/dta.d.ts +0 -3
  123. package/dist/commonjs/lib/middlewares/dta.js +0 -14
  124. package/dist/commonjs/lib/middlewares/hsts.d.ts +0 -4
  125. package/dist/commonjs/lib/middlewares/hsts.js +0 -23
  126. package/dist/commonjs/lib/middlewares/index.d.ts +0 -13
  127. package/dist/commonjs/lib/middlewares/index.js +0 -28
  128. package/dist/commonjs/lib/middlewares/methodnoallow.d.ts +0 -3
  129. package/dist/commonjs/lib/middlewares/methodnoallow.js +0 -22
  130. package/dist/commonjs/lib/middlewares/noopen.d.ts +0 -4
  131. package/dist/commonjs/lib/middlewares/noopen.js +0 -17
  132. package/dist/commonjs/lib/middlewares/nosniff.d.ts +0 -4
  133. package/dist/commonjs/lib/middlewares/nosniff.js +0 -30
  134. package/dist/commonjs/lib/middlewares/referrerPolicy.d.ts +0 -4
  135. package/dist/commonjs/lib/middlewares/referrerPolicy.js +0 -36
  136. package/dist/commonjs/lib/middlewares/xframe.d.ts +0 -4
  137. package/dist/commonjs/lib/middlewares/xframe.js +0 -19
  138. package/dist/commonjs/lib/middlewares/xssProtection.d.ts +0 -4
  139. package/dist/commonjs/lib/middlewares/xssProtection.js +0 -16
  140. package/dist/commonjs/lib/utils.d.ts +0 -19
  141. package/dist/commonjs/lib/utils.js +0 -206
  142. package/dist/commonjs/package.json +0 -3
  143. package/dist/commonjs/types.d.ts +0 -10
  144. package/dist/commonjs/types.js +0 -5
  145. package/dist/esm/agent.d.ts +0 -6
  146. package/dist/esm/agent.js +0 -11
  147. package/dist/esm/app/extend/agent.d.ts +0 -5
  148. package/dist/esm/app/extend/agent.js +0 -8
  149. package/dist/esm/app/extend/application.d.ts +0 -16
  150. package/dist/esm/app/extend/application.js +0 -32
  151. package/dist/esm/app/extend/context.d.ts +0 -68
  152. package/dist/esm/app/extend/context.js +0 -244
  153. package/dist/esm/app/extend/helper.d.ts +0 -12
  154. package/dist/esm/app/extend/helper.js +0 -5
  155. package/dist/esm/app/extend/response.d.ts +0 -41
  156. package/dist/esm/app/extend/response.js +0 -82
  157. package/dist/esm/app/middleware/securities.d.ts +0 -4
  158. package/dist/esm/app/middleware/securities.js +0 -50
  159. package/dist/esm/app.d.ts +0 -6
  160. package/dist/esm/app.js +0 -26
  161. package/dist/esm/config/config.default.d.ts +0 -871
  162. package/dist/esm/config/config.default.js +0 -351
  163. package/dist/esm/config/config.local.d.ts +0 -5
  164. package/dist/esm/config/config.local.js +0 -8
  165. package/dist/esm/index.d.ts +0 -1
  166. package/dist/esm/index.js +0 -2
  167. package/dist/esm/lib/extend/safe_curl.d.ts +0 -16
  168. package/dist/esm/lib/extend/safe_curl.js +0 -25
  169. package/dist/esm/lib/helper/cliFilter.d.ts +0 -4
  170. package/dist/esm/lib/helper/cliFilter.js +0 -17
  171. package/dist/esm/lib/helper/escape.d.ts +0 -2
  172. package/dist/esm/lib/helper/escape.js +0 -3
  173. package/dist/esm/lib/helper/escapeShellArg.d.ts +0 -1
  174. package/dist/esm/lib/helper/escapeShellArg.js +0 -5
  175. package/dist/esm/lib/helper/escapeShellCmd.d.ts +0 -1
  176. package/dist/esm/lib/helper/escapeShellCmd.js +0 -14
  177. package/dist/esm/lib/helper/index.d.ts +0 -21
  178. package/dist/esm/lib/helper/index.js +0 -21
  179. package/dist/esm/lib/helper/shtml.d.ts +0 -2
  180. package/dist/esm/lib/helper/shtml.js +0 -70
  181. package/dist/esm/lib/helper/sjs.d.ts +0 -4
  182. package/dist/esm/lib/helper/sjs.js +0 -49
  183. package/dist/esm/lib/helper/sjson.d.ts +0 -1
  184. package/dist/esm/lib/helper/sjson.js +0 -39
  185. package/dist/esm/lib/helper/spath.d.ts +0 -5
  186. package/dist/esm/lib/helper/spath.js +0 -25
  187. package/dist/esm/lib/helper/surl.d.ts +0 -2
  188. package/dist/esm/lib/helper/surl.js +0 -30
  189. package/dist/esm/lib/middlewares/csp.d.ts +0 -4
  190. package/dist/esm/lib/middlewares/csp.js +0 -63
  191. package/dist/esm/lib/middlewares/csrf.d.ts +0 -4
  192. package/dist/esm/lib/middlewares/csrf.js +0 -37
  193. package/dist/esm/lib/middlewares/dta.d.ts +0 -3
  194. package/dist/esm/lib/middlewares/dta.js +0 -12
  195. package/dist/esm/lib/middlewares/hsts.d.ts +0 -4
  196. package/dist/esm/lib/middlewares/hsts.js +0 -21
  197. package/dist/esm/lib/middlewares/index.d.ts +0 -13
  198. package/dist/esm/lib/middlewares/index.js +0 -23
  199. package/dist/esm/lib/middlewares/methodnoallow.d.ts +0 -3
  200. package/dist/esm/lib/middlewares/methodnoallow.js +0 -20
  201. package/dist/esm/lib/middlewares/noopen.d.ts +0 -4
  202. package/dist/esm/lib/middlewares/noopen.js +0 -15
  203. package/dist/esm/lib/middlewares/nosniff.d.ts +0 -4
  204. package/dist/esm/lib/middlewares/nosniff.js +0 -28
  205. package/dist/esm/lib/middlewares/referrerPolicy.d.ts +0 -4
  206. package/dist/esm/lib/middlewares/referrerPolicy.js +0 -34
  207. package/dist/esm/lib/middlewares/xframe.d.ts +0 -4
  208. package/dist/esm/lib/middlewares/xframe.js +0 -17
  209. package/dist/esm/lib/middlewares/xssProtection.d.ts +0 -4
  210. package/dist/esm/lib/middlewares/xssProtection.js +0 -14
  211. package/dist/esm/lib/utils.d.ts +0 -19
  212. package/dist/esm/lib/utils.js +0 -194
  213. package/dist/esm/package.json +0 -3
  214. package/dist/esm/types.d.ts +0 -10
  215. package/dist/esm/types.js +0 -3
  216. package/dist/package.json +0 -4
  217. package/src/agent.ts +0 -14
  218. package/src/app/extend/agent.ts +0 -14
  219. package/src/app/extend/application.ts +0 -51
  220. package/src/app/extend/context.ts +0 -285
  221. package/src/app/extend/helper.ts +0 -5
  222. package/src/app/extend/response.ts +0 -95
  223. package/src/app/middleware/securities.ts +0 -63
  224. package/src/app.ts +0 -31
  225. package/src/config/config.default.ts +0 -379
  226. package/src/config/config.local.ts +0 -9
  227. package/src/index.ts +0 -1
  228. package/src/lib/extend/safe_curl.ts +0 -35
  229. package/src/lib/helper/cliFilter.ts +0 -20
  230. package/src/lib/helper/escape.ts +0 -3
  231. package/src/lib/helper/escapeShellArg.ts +0 -4
  232. package/src/lib/helper/escapeShellCmd.ts +0 -16
  233. package/src/lib/helper/index.ts +0 -21
  234. package/src/lib/helper/shtml.ts +0 -77
  235. package/src/lib/helper/sjs.ts +0 -57
  236. package/src/lib/helper/sjson.ts +0 -35
  237. package/src/lib/helper/spath.ts +0 -27
  238. package/src/lib/helper/surl.ts +0 -35
  239. package/src/lib/middlewares/csp.ts +0 -70
  240. package/src/lib/middlewares/csrf.ts +0 -44
  241. package/src/lib/middlewares/dta.ts +0 -13
  242. package/src/lib/middlewares/hsts.ts +0 -24
  243. package/src/lib/middlewares/index.ts +0 -23
  244. package/src/lib/middlewares/methodnoallow.ts +0 -23
  245. package/src/lib/middlewares/noopen.ts +0 -18
  246. package/src/lib/middlewares/nosniff.ts +0 -32
  247. package/src/lib/middlewares/referrerPolicy.ts +0 -39
  248. package/src/lib/middlewares/xframe.ts +0 -20
  249. package/src/lib/middlewares/xssProtection.ts +0 -17
  250. package/src/lib/utils.ts +0 -208
  251. package/src/types.ts +0 -16
  252. 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": "4.0.1",
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/security.git"
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.19.0"
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.6",
42
- "egg-path-matching": "^2.1.0",
75
+ "csrf": "^3.1.0",
76
+ "egg-path-matching": "^2.0.0",
43
77
  "escape-html": "^1.0.3",
44
- "extend": "^3.0.1",
78
+ "extend": "^3.0.2",
45
79
  "koa-compose": "^4.1.0",
46
80
  "matcher": "^4.0.0",
47
- "nanoid": "^3.3.8",
48
- "type-is": "^1.6.18",
49
- "xss": "^1.0.3",
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": "22",
63
- "@types/type-is": "^1.6.7",
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
- "supertest": "^6.3.3",
74
- "tshy": "3",
75
- "tshy-after": "1",
76
- "typescript": "5"
77
- },
78
- "scripts": {
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
- "types": "./dist/commonjs/index.d.ts",
114
- "main": "./dist/commonjs/index.js",
115
- "module": "./dist/esm/index.js"
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
+ }
@@ -1,6 +0,0 @@
1
- import type { ILifecycleBoot, EggCore } from '@eggjs/core';
2
- export default class AgentBoot implements ILifecycleBoot {
3
- private readonly agent;
4
- constructor(agent: EggCore);
5
- configWillLoad(): Promise<void>;
6
- }
@@ -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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