@eggjs/security 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +569 -0
  3. package/README.zh-CN.md +441 -0
  4. package/dist/commonjs/agent.d.ts +6 -0
  5. package/dist/commonjs/agent.js +14 -0
  6. package/dist/commonjs/app/extend/agent.d.ts +5 -0
  7. package/dist/commonjs/app/extend/agent.js +11 -0
  8. package/dist/commonjs/app/extend/application.d.ts +16 -0
  9. package/dist/commonjs/app/extend/application.js +35 -0
  10. package/dist/commonjs/app/extend/context.d.ts +68 -0
  11. package/dist/commonjs/app/extend/context.js +283 -0
  12. package/dist/commonjs/app/extend/helper.d.ts +12 -0
  13. package/dist/commonjs/app/extend/helper.js +10 -0
  14. package/dist/commonjs/app/extend/response.d.ts +41 -0
  15. package/dist/commonjs/app/extend/response.js +85 -0
  16. package/dist/commonjs/app/middleware/securities.d.ts +4 -0
  17. package/dist/commonjs/app/middleware/securities.js +55 -0
  18. package/dist/commonjs/app.d.ts +6 -0
  19. package/dist/commonjs/app.js +29 -0
  20. package/dist/commonjs/config/config.default.d.ts +871 -0
  21. package/dist/commonjs/config/config.default.js +357 -0
  22. package/dist/commonjs/config/config.local.d.ts +5 -0
  23. package/dist/commonjs/config/config.local.js +10 -0
  24. package/dist/commonjs/index.d.ts +1 -0
  25. package/dist/commonjs/index.js +14 -0
  26. package/dist/commonjs/lib/extend/safe_curl.d.ts +16 -0
  27. package/dist/commonjs/lib/extend/safe_curl.js +28 -0
  28. package/dist/commonjs/lib/helper/cliFilter.d.ts +4 -0
  29. package/dist/commonjs/lib/helper/cliFilter.js +20 -0
  30. package/dist/commonjs/lib/helper/escape.d.ts +2 -0
  31. package/dist/commonjs/lib/helper/escape.js +8 -0
  32. package/dist/commonjs/lib/helper/escapeShellArg.d.ts +1 -0
  33. package/dist/commonjs/lib/helper/escapeShellArg.js +8 -0
  34. package/dist/commonjs/lib/helper/escapeShellCmd.d.ts +1 -0
  35. package/dist/commonjs/lib/helper/escapeShellCmd.js +17 -0
  36. package/dist/commonjs/lib/helper/index.d.ts +21 -0
  37. package/dist/commonjs/lib/helper/index.js +26 -0
  38. package/dist/commonjs/lib/helper/shtml.d.ts +2 -0
  39. package/dist/commonjs/lib/helper/shtml.js +76 -0
  40. package/dist/commonjs/lib/helper/sjs.d.ts +4 -0
  41. package/dist/commonjs/lib/helper/sjs.js +52 -0
  42. package/dist/commonjs/lib/helper/sjson.d.ts +1 -0
  43. package/dist/commonjs/lib/helper/sjson.js +45 -0
  44. package/dist/commonjs/lib/helper/spath.d.ts +5 -0
  45. package/dist/commonjs/lib/helper/spath.js +28 -0
  46. package/dist/commonjs/lib/helper/surl.d.ts +2 -0
  47. package/dist/commonjs/lib/helper/surl.js +33 -0
  48. package/dist/commonjs/lib/middlewares/csp.d.ts +4 -0
  49. package/dist/commonjs/lib/middlewares/csp.js +68 -0
  50. package/dist/commonjs/lib/middlewares/csrf.d.ts +4 -0
  51. package/dist/commonjs/lib/middlewares/csrf.js +42 -0
  52. package/dist/commonjs/lib/middlewares/dta.d.ts +3 -0
  53. package/dist/commonjs/lib/middlewares/dta.js +14 -0
  54. package/dist/commonjs/lib/middlewares/hsts.d.ts +4 -0
  55. package/dist/commonjs/lib/middlewares/hsts.js +23 -0
  56. package/dist/commonjs/lib/middlewares/index.d.ts +13 -0
  57. package/dist/commonjs/lib/middlewares/index.js +28 -0
  58. package/dist/commonjs/lib/middlewares/methodnoallow.d.ts +3 -0
  59. package/dist/commonjs/lib/middlewares/methodnoallow.js +22 -0
  60. package/dist/commonjs/lib/middlewares/noopen.d.ts +4 -0
  61. package/dist/commonjs/lib/middlewares/noopen.js +17 -0
  62. package/dist/commonjs/lib/middlewares/nosniff.d.ts +4 -0
  63. package/dist/commonjs/lib/middlewares/nosniff.js +30 -0
  64. package/dist/commonjs/lib/middlewares/referrerPolicy.d.ts +4 -0
  65. package/dist/commonjs/lib/middlewares/referrerPolicy.js +36 -0
  66. package/dist/commonjs/lib/middlewares/xframe.d.ts +4 -0
  67. package/dist/commonjs/lib/middlewares/xframe.js +19 -0
  68. package/dist/commonjs/lib/middlewares/xssProtection.d.ts +4 -0
  69. package/dist/commonjs/lib/middlewares/xssProtection.js +16 -0
  70. package/dist/commonjs/lib/utils.d.ts +19 -0
  71. package/dist/commonjs/lib/utils.js +206 -0
  72. package/dist/commonjs/package.json +3 -0
  73. package/dist/commonjs/types.d.ts +10 -0
  74. package/dist/commonjs/types.js +5 -0
  75. package/dist/esm/agent.d.ts +6 -0
  76. package/dist/esm/agent.js +11 -0
  77. package/dist/esm/app/extend/agent.d.ts +5 -0
  78. package/dist/esm/app/extend/agent.js +8 -0
  79. package/dist/esm/app/extend/application.d.ts +16 -0
  80. package/dist/esm/app/extend/application.js +32 -0
  81. package/dist/esm/app/extend/context.d.ts +68 -0
  82. package/dist/esm/app/extend/context.js +244 -0
  83. package/dist/esm/app/extend/helper.d.ts +12 -0
  84. package/dist/esm/app/extend/helper.js +5 -0
  85. package/dist/esm/app/extend/response.d.ts +41 -0
  86. package/dist/esm/app/extend/response.js +82 -0
  87. package/dist/esm/app/middleware/securities.d.ts +4 -0
  88. package/dist/esm/app/middleware/securities.js +50 -0
  89. package/dist/esm/app.d.ts +6 -0
  90. package/dist/esm/app.js +26 -0
  91. package/dist/esm/config/config.default.d.ts +871 -0
  92. package/dist/esm/config/config.default.js +351 -0
  93. package/dist/esm/config/config.local.d.ts +5 -0
  94. package/dist/esm/config/config.local.js +8 -0
  95. package/dist/esm/index.d.ts +1 -0
  96. package/dist/esm/index.js +12 -0
  97. package/dist/esm/lib/extend/safe_curl.d.ts +16 -0
  98. package/dist/esm/lib/extend/safe_curl.js +25 -0
  99. package/dist/esm/lib/helper/cliFilter.d.ts +4 -0
  100. package/dist/esm/lib/helper/cliFilter.js +17 -0
  101. package/dist/esm/lib/helper/escape.d.ts +2 -0
  102. package/dist/esm/lib/helper/escape.js +3 -0
  103. package/dist/esm/lib/helper/escapeShellArg.d.ts +1 -0
  104. package/dist/esm/lib/helper/escapeShellArg.js +5 -0
  105. package/dist/esm/lib/helper/escapeShellCmd.d.ts +1 -0
  106. package/dist/esm/lib/helper/escapeShellCmd.js +14 -0
  107. package/dist/esm/lib/helper/index.d.ts +21 -0
  108. package/dist/esm/lib/helper/index.js +21 -0
  109. package/dist/esm/lib/helper/shtml.d.ts +2 -0
  110. package/dist/esm/lib/helper/shtml.js +70 -0
  111. package/dist/esm/lib/helper/sjs.d.ts +4 -0
  112. package/dist/esm/lib/helper/sjs.js +49 -0
  113. package/dist/esm/lib/helper/sjson.d.ts +1 -0
  114. package/dist/esm/lib/helper/sjson.js +39 -0
  115. package/dist/esm/lib/helper/spath.d.ts +5 -0
  116. package/dist/esm/lib/helper/spath.js +25 -0
  117. package/dist/esm/lib/helper/surl.d.ts +2 -0
  118. package/dist/esm/lib/helper/surl.js +30 -0
  119. package/dist/esm/lib/middlewares/csp.d.ts +4 -0
  120. package/dist/esm/lib/middlewares/csp.js +63 -0
  121. package/dist/esm/lib/middlewares/csrf.d.ts +4 -0
  122. package/dist/esm/lib/middlewares/csrf.js +37 -0
  123. package/dist/esm/lib/middlewares/dta.d.ts +3 -0
  124. package/dist/esm/lib/middlewares/dta.js +12 -0
  125. package/dist/esm/lib/middlewares/hsts.d.ts +4 -0
  126. package/dist/esm/lib/middlewares/hsts.js +21 -0
  127. package/dist/esm/lib/middlewares/index.d.ts +13 -0
  128. package/dist/esm/lib/middlewares/index.js +23 -0
  129. package/dist/esm/lib/middlewares/methodnoallow.d.ts +3 -0
  130. package/dist/esm/lib/middlewares/methodnoallow.js +20 -0
  131. package/dist/esm/lib/middlewares/noopen.d.ts +4 -0
  132. package/dist/esm/lib/middlewares/noopen.js +15 -0
  133. package/dist/esm/lib/middlewares/nosniff.d.ts +4 -0
  134. package/dist/esm/lib/middlewares/nosniff.js +28 -0
  135. package/dist/esm/lib/middlewares/referrerPolicy.d.ts +4 -0
  136. package/dist/esm/lib/middlewares/referrerPolicy.js +34 -0
  137. package/dist/esm/lib/middlewares/xframe.d.ts +4 -0
  138. package/dist/esm/lib/middlewares/xframe.js +17 -0
  139. package/dist/esm/lib/middlewares/xssProtection.d.ts +4 -0
  140. package/dist/esm/lib/middlewares/xssProtection.js +14 -0
  141. package/dist/esm/lib/utils.d.ts +19 -0
  142. package/dist/esm/lib/utils.js +194 -0
  143. package/dist/esm/package.json +3 -0
  144. package/dist/esm/types.d.ts +10 -0
  145. package/dist/esm/types.js +3 -0
  146. package/dist/package.json +4 -0
  147. package/package.json +116 -0
  148. package/src/agent.ts +14 -0
  149. package/src/app/extend/agent.ts +14 -0
  150. package/src/app/extend/application.ts +51 -0
  151. package/src/app/extend/context.ts +282 -0
  152. package/src/app/extend/helper.ts +5 -0
  153. package/src/app/extend/response.ts +95 -0
  154. package/src/app/middleware/securities.ts +63 -0
  155. package/src/app.ts +31 -0
  156. package/src/config/config.default.ts +379 -0
  157. package/src/config/config.local.ts +9 -0
  158. package/src/index.ts +12 -0
  159. package/src/lib/extend/safe_curl.ts +35 -0
  160. package/src/lib/helper/cliFilter.ts +20 -0
  161. package/src/lib/helper/escape.ts +3 -0
  162. package/src/lib/helper/escapeShellArg.ts +4 -0
  163. package/src/lib/helper/escapeShellCmd.ts +16 -0
  164. package/src/lib/helper/index.ts +21 -0
  165. package/src/lib/helper/shtml.ts +77 -0
  166. package/src/lib/helper/sjs.ts +57 -0
  167. package/src/lib/helper/sjson.ts +35 -0
  168. package/src/lib/helper/spath.ts +27 -0
  169. package/src/lib/helper/surl.ts +35 -0
  170. package/src/lib/middlewares/csp.ts +70 -0
  171. package/src/lib/middlewares/csrf.ts +44 -0
  172. package/src/lib/middlewares/dta.ts +13 -0
  173. package/src/lib/middlewares/hsts.ts +24 -0
  174. package/src/lib/middlewares/index.ts +23 -0
  175. package/src/lib/middlewares/methodnoallow.ts +23 -0
  176. package/src/lib/middlewares/noopen.ts +18 -0
  177. package/src/lib/middlewares/nosniff.ts +32 -0
  178. package/src/lib/middlewares/referrerPolicy.ts +39 -0
  179. package/src/lib/middlewares/xframe.ts +20 -0
  180. package/src/lib/middlewares/xssProtection.ts +17 -0
  181. package/src/lib/utils.ts +208 -0
  182. package/src/types.ts +16 -0
  183. package/src/typings/index.d.ts +4 -0
@@ -0,0 +1,194 @@
1
+ import { normalize } from 'node:path';
2
+ import matcher from 'matcher';
3
+ import IP from '@eggjs/ip';
4
+ /**
5
+ * Check whether a domain is in the safe domain white list or not.
6
+ * @param {String} domain The inputted domain.
7
+ * @param {Array<string>} whiteList The white list for domain.
8
+ * @return {Boolean} If the `domain` is in the white list, return true; otherwise false.
9
+ */
10
+ export function isSafeDomain(domain, whiteList) {
11
+ // domain must be string, otherwise return false
12
+ if (typeof domain !== 'string')
13
+ return false;
14
+ // Ignore case sensitive first
15
+ domain = domain.toLowerCase();
16
+ // add prefix `.`, because all domains in white list start with `.`
17
+ const hostname = '.' + domain;
18
+ return whiteList.some(rule => {
19
+ // Check whether we've got '*' as a wild character symbol
20
+ if (rule.includes('*')) {
21
+ return matcher.isMatch(domain, rule);
22
+ }
23
+ // If domain is an absolute path such as `http://...`
24
+ // We can directly check whether it directly equals to `domain`
25
+ // And we don't need to cope with `endWith`.
26
+ if (domain === rule)
27
+ return true;
28
+ // ensure wwweggjs.com not match eggjs.com
29
+ if (!/^\./.test(rule))
30
+ rule = `.${rule}`;
31
+ return hostname.endsWith(rule);
32
+ });
33
+ }
34
+ export function isSafePath(path, ctx) {
35
+ path = '.' + path;
36
+ if (path.includes('%')) {
37
+ try {
38
+ path = decodeURIComponent(path);
39
+ }
40
+ catch (e) {
41
+ if (ctx.app.config.env === 'local' || ctx.app.config.env === 'unittest') {
42
+ // not under production environment, output log
43
+ ctx.coreLogger.warn('[@eggjs/security: dta global block] : decode file path %j failed.', path);
44
+ }
45
+ }
46
+ }
47
+ const normalizePath = normalize(path);
48
+ return !(normalizePath.startsWith('../') || normalizePath.startsWith('..\\'));
49
+ }
50
+ export function checkIfIgnore(opts, ctx) {
51
+ // check opts.enable first
52
+ if (!opts.enable)
53
+ return true;
54
+ return !opts.matching?.(ctx);
55
+ }
56
+ const IP_RE = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
57
+ const topDomains = {};
58
+ [
59
+ '.net.cn', '.gov.cn', '.org.cn', '.com.cn',
60
+ ].forEach(item => {
61
+ topDomains[item] = 2 - item.split('.').length;
62
+ });
63
+ export function getCookieDomain(hostname) {
64
+ // TODO(fengmk2): support ipv6
65
+ if (IP_RE.test(hostname)) {
66
+ return hostname;
67
+ }
68
+ // app.test.domain.com => .test.domain.com
69
+ // app.stable.domain.com => .domain.com
70
+ // app.domain.com => .domain.com
71
+ // domain=.domain.com;
72
+ const splits = hostname.split('.');
73
+ let index = -2;
74
+ // only when `*.test.*.com` set `.test.*.com`
75
+ if (splits.length >= 4 && splits[splits.length - 3] === 'test') {
76
+ index = -3;
77
+ }
78
+ let domain = getDomain(splits, index);
79
+ if (topDomains[domain]) {
80
+ // app.foo.org.cn => .foo.org.cn
81
+ domain = getDomain(splits, index + topDomains[domain]);
82
+ }
83
+ return domain;
84
+ }
85
+ function getDomain(splits, index) {
86
+ return '.' + splits.slice(index).join('.');
87
+ }
88
+ export function merge(origin, opts) {
89
+ if (!opts) {
90
+ return origin;
91
+ }
92
+ const res = {};
93
+ const originKeys = Object.keys(origin);
94
+ for (let i = 0; i < originKeys.length; i++) {
95
+ const key = originKeys[i];
96
+ res[key] = origin[key];
97
+ }
98
+ const keys = Object.keys(opts);
99
+ for (let i = 0; i < keys.length; i++) {
100
+ const key = keys[i];
101
+ res[key] = opts[key];
102
+ }
103
+ return res;
104
+ }
105
+ export function preprocessConfig(config) {
106
+ // transfer ssrf.ipBlackList to ssrf.checkAddress
107
+ // ssrf.ipExceptionList can easily pick out unwanted ips from ipBlackList
108
+ // checkAddress has higher priority than ipBlackList
109
+ const ssrf = config.ssrf;
110
+ if (ssrf && ssrf.ipBlackList && !ssrf.checkAddress) {
111
+ const blackList = ssrf.ipBlackList.map(getContains);
112
+ const exceptionList = (ssrf.ipExceptionList || []).map(getContains);
113
+ const hostnameExceptionList = ssrf.hostnameExceptionList;
114
+ ssrf.checkAddress = (ipAddresses, _family, hostname) => {
115
+ // Check white hostname first
116
+ if (hostname && hostnameExceptionList) {
117
+ if (hostnameExceptionList.includes(hostname)) {
118
+ return true;
119
+ }
120
+ }
121
+ // ipAddresses will be array address on Node.js >= 20
122
+ // [
123
+ // { address: '220.181.125.241', family: 4 },
124
+ // { address: '240e:964:ea02:b00:3::3ec', family: 6 }
125
+ // ]
126
+ if (!Array.isArray(ipAddresses)) {
127
+ ipAddresses = [ipAddresses];
128
+ }
129
+ for (const ipAddress of ipAddresses) {
130
+ let address;
131
+ if (typeof ipAddress === 'string') {
132
+ address = ipAddress;
133
+ }
134
+ else {
135
+ // FIXME: should support ipv6
136
+ if (ipAddress.family === 6) {
137
+ continue;
138
+ }
139
+ address = ipAddress.address;
140
+ }
141
+ // check white list first
142
+ for (const exception of exceptionList) {
143
+ if (exception(address)) {
144
+ return true;
145
+ }
146
+ }
147
+ // check black list
148
+ for (const contains of blackList) {
149
+ if (contains(address)) {
150
+ return false;
151
+ }
152
+ }
153
+ }
154
+ // default allow
155
+ return true;
156
+ };
157
+ }
158
+ // Make sure that `whiteList` or `protocolWhiteList` is case insensitive
159
+ config.domainWhiteList = config.domainWhiteList || [];
160
+ config.domainWhiteList = config.domainWhiteList.map((domain) => domain.toLowerCase());
161
+ config.protocolWhiteList = config.protocolWhiteList || [];
162
+ config.protocolWhiteList = config.protocolWhiteList.map((protocol) => protocol.toLowerCase());
163
+ // Make sure refererWhiteList is case insensitive
164
+ if (config.csrf && config.csrf.refererWhiteList) {
165
+ config.csrf.refererWhiteList = config.csrf.refererWhiteList.map((ref) => ref.toLowerCase());
166
+ }
167
+ // Directly converted to Set collection by a private property (not documented),
168
+ // And we NO LONGER need to do conversion in `foreach` again and again in `lib/helper/surl.ts`.
169
+ const protocolWhiteListSet = new Set(config.protocolWhiteList);
170
+ protocolWhiteListSet.add('http');
171
+ protocolWhiteListSet.add('https');
172
+ protocolWhiteListSet.add('file');
173
+ protocolWhiteListSet.add('data');
174
+ Object.defineProperty(config, '__protocolWhiteListSet', {
175
+ value: protocolWhiteListSet,
176
+ enumerable: false,
177
+ });
178
+ }
179
+ export function getFromUrl(url, prop) {
180
+ try {
181
+ const parsed = new URL(url);
182
+ return prop ? Reflect.get(parsed, prop) : parsed;
183
+ }
184
+ catch {
185
+ return null;
186
+ }
187
+ }
188
+ function getContains(ip) {
189
+ if (IP.isV4Format(ip) || IP.isV6Format(ip)) {
190
+ return (address) => address === ip;
191
+ }
192
+ return IP.cidrSubnet(ip).contains;
193
+ }
194
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDdEMsT0FBTyxPQUFPLE1BQU0sU0FBUyxDQUFDO0FBQzlCLE9BQU8sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUszQjs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxZQUFZLENBQUMsTUFBYyxFQUFFLFNBQW1CO0lBQzlELGdEQUFnRDtJQUNoRCxJQUFJLE9BQU8sTUFBTSxLQUFLLFFBQVE7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUM3Qyw4QkFBOEI7SUFDOUIsTUFBTSxHQUFHLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUM5QixtRUFBbUU7SUFDbkUsTUFBTSxRQUFRLEdBQUcsR0FBRyxHQUFHLE1BQU0sQ0FBQztJQUU5QixPQUFPLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUU7UUFDM0IseURBQXlEO1FBQ3pELElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3ZCLE9BQU8sT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDdkMsQ0FBQztRQUNELHFEQUFxRDtRQUNyRCwrREFBK0Q7UUFDL0QsNENBQTRDO1FBQzVDLElBQUksTUFBTSxLQUFLLElBQUk7WUFBRSxPQUFPLElBQUksQ0FBQztRQUNqQywwQ0FBMEM7UUFDMUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBQUUsSUFBSSxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7UUFDekMsT0FBTyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2pDLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELE1BQU0sVUFBVSxVQUFVLENBQUMsSUFB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
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "module"
3
+ }
@@ -0,0 +1,10 @@
1
+ import './app/extend/application.js';
2
+ import './app/extend/context.js';
3
+ import type { SecurityConfig, SecurityHelperConfig } from './config/config.default.js';
4
+ export type * from './config/config.default.js';
5
+ declare module '@eggjs/core' {
6
+ interface EggAppConfig {
7
+ security: SecurityConfig;
8
+ helper: SecurityHelperConfig;
9
+ }
10
+ }
@@ -0,0 +1,3 @@
1
+ import './app/extend/application.js';
2
+ import './app/extend/context.js';
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyw2QkFBNkIsQ0FBQztBQUNyQyxPQUFPLHlCQUF5QixDQUFDIn0=
@@ -0,0 +1,4 @@
1
+ {
2
+ "name": "@eggjs/security",
3
+ "version": "4.0.0"
4
+ }
package/package.json ADDED
@@ -0,0 +1,116 @@
1
+ {
2
+ "name": "@eggjs/security",
3
+ "version": "4.0.0",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
7
+ "description": "security plugin in egg framework",
8
+ "eggPlugin": {
9
+ "name": "security",
10
+ "optionalDependencies": [
11
+ "session"
12
+ ],
13
+ "exports": {
14
+ "import": "./dist/esm",
15
+ "require": "./dist/commonjs",
16
+ "typescript": "./src"
17
+ }
18
+ },
19
+ "keywords": [
20
+ "egg",
21
+ "eggPlugin",
22
+ "egg-plugin",
23
+ "security"
24
+ ],
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "git+https://github.com/eggjs/security.git"
28
+ },
29
+ "bugs": {
30
+ "url": "https://github.com/eggjs/egg/issues"
31
+ },
32
+ "homepage": "https://github.com/eggjs/security#readme",
33
+ "author": "jtyjty99999",
34
+ "license": "MIT",
35
+ "engines": {
36
+ "node": ">= 18.19.0"
37
+ },
38
+ "dependencies": {
39
+ "@eggjs/core": "^6.2.13",
40
+ "@eggjs/ip": "^2.1.0",
41
+ "csrf": "^3.0.6",
42
+ "egg-path-matching": "^2.1.0",
43
+ "escape-html": "^1.0.3",
44
+ "extend": "^3.0.1",
45
+ "koa-compose": "^4.1.0",
46
+ "matcher": "^4.0.0",
47
+ "nanoid": "^3.3.8",
48
+ "type-is": "^1.6.18",
49
+ "xss": "^1.0.3",
50
+ "zod": "^3.24.1"
51
+ },
52
+ "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
+ "@types/escape-html": "^1.0.4",
59
+ "@types/extend": "^3.0.4",
60
+ "@types/koa-compose": "^3.2.8",
61
+ "@types/mocha": "10",
62
+ "@types/node": "22",
63
+ "@types/type-is": "^1.6.7",
64
+ "beautify-benchmark": "^0.2.4",
65
+ "benchmark": "^2.1.4",
66
+ "egg": "^4.0.1",
67
+ "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
+ "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"
108
+ },
109
+ "files": [
110
+ "dist",
111
+ "src"
112
+ ],
113
+ "types": "./dist/commonjs/index.d.ts",
114
+ "main": "./dist/commonjs/index.js",
115
+ "module": "./dist/esm/index.js"
116
+ }
package/src/agent.ts ADDED
@@ -0,0 +1,14 @@
1
+ import type { ILifecycleBoot, EggCore } from '@eggjs/core';
2
+ import { preprocessConfig } from './lib/utils.js';
3
+
4
+ export default class AgentBoot implements ILifecycleBoot {
5
+ private readonly agent;
6
+
7
+ constructor(agent: EggCore) {
8
+ this.agent = agent;
9
+ }
10
+
11
+ async configWillLoad() {
12
+ preprocessConfig(this.agent.config.security);
13
+ }
14
+ }
@@ -0,0 +1,14 @@
1
+ import { EggCore } from '@eggjs/core';
2
+ import {
3
+ safeCurlForApplication,
4
+ type HttpClientRequestURL,
5
+ type HttpClientOptions,
6
+ type HttpClientResponse,
7
+ } from '../../lib/extend/safe_curl.js';
8
+
9
+ export default class SecurityAgent extends EggCore {
10
+ async safeCurl<T = any>(
11
+ url: HttpClientRequestURL, options?: HttpClientOptions): Promise<HttpClientResponse<T>> {
12
+ return await safeCurlForApplication<T>(this, url, options);
13
+ }
14
+ }
@@ -0,0 +1,51 @@
1
+ import { EggCore } from '@eggjs/core';
2
+ import {
3
+ safeCurlForApplication,
4
+ type HttpClientRequestURL,
5
+ type HttpClientOptions,
6
+ type HttpClientResponse,
7
+ } from '../../lib/extend/safe_curl.js';
8
+
9
+ const INPUT_CSRF = '\r\n<input type="hidden" name="_csrf" value="{{ctx.csrf}}" /></form>';
10
+ const INJECTION_DEFENSE = '<!--for injection--><!--</html>--><!--for injection-->';
11
+
12
+ export default class SecurityApplication extends EggCore {
13
+ injectCsrf(html: string) {
14
+ html = html.replace(/(<form.*?>)([\s\S]*?)<\/form>/gi, (_, $1, $2) => {
15
+ const match = $2;
16
+ if (match.indexOf('name="_csrf"') !== -1 || match.indexOf('name=\'_csrf\'') !== -1) {
17
+ return $1 + match + '</form>';
18
+ }
19
+ return $1 + match + INPUT_CSRF;
20
+ });
21
+ return html;
22
+ }
23
+
24
+ injectNonce(html: string) {
25
+ html = html.replace(/<script(.*?)>([\s\S]*?)<\/script[^>]*?>/gi, (_, $1, $2) => {
26
+ if (!$1.includes('nonce=')) {
27
+ $1 += ' nonce="{{ctx.nonce}}"';
28
+ }
29
+ return '<script' + $1 + '>' + $2 + '</script>';
30
+ });
31
+ return html;
32
+ }
33
+
34
+ injectHijackingDefense(html: string) {
35
+ return INJECTION_DEFENSE + html + INJECTION_DEFENSE;
36
+ }
37
+
38
+ async safeCurl<T = any>(
39
+ url: HttpClientRequestURL, options?: HttpClientOptions): Promise<HttpClientResponse<T>> {
40
+ return await safeCurlForApplication<T>(this, url, options);
41
+ }
42
+ }
43
+
44
+ declare module '@eggjs/core' {
45
+ interface EggCore {
46
+ injectCsrf(html: string): string;
47
+ injectNonce(html: string): string;
48
+ injectHijackingDefense(html: string): string;
49
+ safeCurl<T = any>(url: HttpClientRequestURL, options?: HttpClientOptions): Promise<HttpClientResponse<T>>;
50
+ }
51
+ }