Skip to content

Commit

Permalink
feat: upgrade deps to latest versions (#82)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: drop Node.js < 14 support
  • Loading branch information
fengmk2 committed May 10, 2023
1 parent 6c5825c commit c3ca817
Show file tree
Hide file tree
Showing 65 changed files with 1,092 additions and 1,426 deletions.
5 changes: 4 additions & 1 deletion .eslintrc
@@ -1,3 +1,6 @@
{
extends: "eslint-config-egg"
"extends": [
"eslint-config-egg",
"eslint-config-egg/lib/rules/enforce-node-prefix"
]
}
2 changes: 1 addition & 1 deletion .github/workflows/nodejs.yml
Expand Up @@ -15,4 +15,4 @@ jobs:
uses: artusjs/github-actions/.github/workflows/node-test.yml@v1
with:
os: 'ubuntu-latest, macos-latest, windows-latest'
version: '8, 10, 12, 14, 16, 18'
version: '14, 16, 18, 20'
File renamed without changes.
40 changes: 18 additions & 22 deletions README.md
Expand Up @@ -22,7 +22,7 @@ Egg's default security plugin, generally no need to configure.
## Install

```bash
$ npm i egg-security
npm i egg-security
```

## Usage & configuration
Expand Down Expand Up @@ -140,7 +140,6 @@ ctx.securityOptions.shtml = {
- `ctx.securityOptions` the current request configuration will overrides the default configuration, but it does not make a deep copy,so pay attention to configure `csp.policy`, it will not be merged.
- If you configure `ctx.securityOptions`,please write unit tests to ensure the code is correct.


## API

### ctx.isSafeDomain(domain)
Expand All @@ -161,7 +160,7 @@ exports.security = {

__usage__

* `ctx.csrf` getter for CSRF token
- `ctx.csrf` getter for CSRF token

Generally used when send POST form request. When page rendering, put `ctx.csrf` into form hidden field or query string.(`_csrf` is the key).
When submitting the form, please submit with the `_csrf` token parameter.
Expand Down Expand Up @@ -232,9 +231,9 @@ Must call `ctx.rotateCsrfSecret()` when user login to ensure each user has indep

### safe redirect

* `ctx.redirect(url)` If url is not in the configuration of the white list, the redirect will be prohibited
- `ctx.redirect(url)` If url is not in the configuration of the white list, the redirect will be prohibited

* `ctx.unsafeRedirect(url)` Not Recommended;
- `ctx.unsafeRedirect(url)` Not Recommended;

Security plugin override `ctx.redirect` method,all redirects will be judged by the domain name.

Expand All @@ -254,13 +253,13 @@ Based on [jsonp-body](https://github.com/node-modules/jsonp-body).

Defense:

* The longest callback function name limit of 50 characters.
* Callback function only allows "[","]","a-zA-Z0123456789_", "$" "." to prevent `xss` or `utf-7` attack.
- The longest callback function name limit of 50 characters.
- Callback function only allows "[","]","a-zA-Z0123456789_", "$" "." to prevent `xss` or `utf-7` attack.

Config:

* callback function default name `_callback`.
* limit - function name limit, default by 50.
- callback function default name `_callback`.
- limit - function name limit, default by 50.

## helper

Expand All @@ -284,7 +283,7 @@ Used for url in html tags (like `<a href=""/><img src=""/>`),please do not call

`helper.surl($value)`

** Mention: Particular attention, if you need to resolve URL use `surl``surl` need warpped in quotes, Otherwise will lead to XSS vulnerability.**
**Mention: Particular attention, if you need to resolve URL use `surl``surl` need warpped in quotes, Otherwise will lead to XSS vulnerability.**

Example: do not use surl

Expand Down Expand Up @@ -345,7 +344,7 @@ console.log(`var foo = "${ctx.helper.sjs(foo)}";`);
If you want to output richtexts in views, you need to use `shtml` helper.
It will do XSS filter, then output html tags to avoid illegal scripts.

** shtml is a very complex process, it will effect server performance, so if you do not need to output HTML, please do not use shtml.**
**shtml is a very complex process, it will effect server performance, so if you do not need to output HTML, please do not use shtml.**

Examples:

Expand All @@ -365,7 +364,7 @@ const value = `<a href="http://www.domain.com">google</a><script>evilcode…</sc
shtml based on [xss](https://github.com/leizongmin/js-xss/), and add filter by domain feature.

- [default rule](https://github.com/leizongmin/js-xss/blob/master/lib/default.js)
- custom rule http://jsxss.com/zh/options.html
- custom rule <http://jsxss.com/zh/options.html>

For example, only support `a` tag, and filter all attributes except for `title`:

Expand Down Expand Up @@ -422,7 +421,7 @@ If you want to output json in javascript without encoding, it will be a risk for
sjson supports json encode,it will iterate all keys in json, then escape all characters in the value to `\x` to avoid XSS attack, and keep the json structure unchanged.
If you want to output json string in your views, please use `${ctx.helper.sjson(var)}`to escape.

**it has a very complex process and will lost performance, so avoid the use as far as possible**
__it has a very complex process and will lost performance, so avoid the use as far as possible__

example:

Expand Down Expand Up @@ -458,7 +457,6 @@ after fix:

Escape command line arguments. Add single quotes around a string and quotes/escapes any existing single quotes allowing you to pass a string directly to a shell function and having it be treated as a single safe argument.


```js
const ip = '127.0.0.1 && cat /etc/passwd'
const cmd = 'ping -c 1 ' + this.helper.escapeShellArg(ip);
Expand All @@ -471,7 +469,6 @@ console.log(cmd);

Command line escape to remove the following characters from the entered command line: ```#&;`|*?~<>^()[]{}$;'", 0x0A and 0xFF```


```js
const ip = '127.0.0.1 && cat /etc/passwd'
const cmd = 'ping -c 1 ' + this.helper.escapeShellCmd(ip);
Expand All @@ -491,7 +488,6 @@ Disabled by default. If your website based on https, we recommend you should ena
- maxAge one year by default `365 * 24 * 3600`
- includeSubdomains false by default


### csp

Default disabled. If you need to enable, please contact your security engineers and determine the opening strategy
Expand Down Expand Up @@ -524,9 +520,9 @@ In a [Server-Side Request Forgery (SSRF)](https://www.owasp.org/index.php/Server

#### Configuration

* ipBlackList(Array) - specific which ip are illegal when request with `safeCurl`.
* ipExceptionList(Array) - specific which ip are legal within ipBlackList.
* checkAddress(Function) - determine the ip by the function's return value, `false` means illegal ip.
- ipBlackList(Array) - specific which ip are illegal when request with `safeCurl`.
- ipExceptionList(Array) - specific which ip are legal within ipBlackList.
- checkAddress(Function) - determine the ip by the function's return value, `false` means illegal ip.

```js
// config/config.default.js
Expand All @@ -553,7 +549,7 @@ exports.security = {

## Other

* Forbid `trace` `track` http methods.
- Forbid `trace` `track` http methods.

<!-- GITCONTRIBUTOR_START -->

Expand All @@ -562,9 +558,9 @@ exports.security = {
|[<img src="https://avatars.githubusercontent.com/u/985607?v=4" width="100px;"/><br/><sub><b>dead-horse</b></sub>](https://github.com/dead-horse)<br/>|[<img src="https://avatars.githubusercontent.com/u/156269?v=4" width="100px;"/><br/><sub><b>fengmk2</b></sub>](https://github.com/fengmk2)<br/>|[<img src="https://avatars.githubusercontent.com/u/893152?v=4" width="100px;"/><br/><sub><b>jtyjty99999</b></sub>](https://github.com/jtyjty99999)<br/>|[<img src="https://avatars.githubusercontent.com/u/360661?v=4" width="100px;"/><br/><sub><b>popomore</b></sub>](https://github.com/popomore)<br/>|[<img src="https://avatars.githubusercontent.com/u/456108?v=4" width="100px;"/><br/><sub><b>shaoshuai0102</b></sub>](https://github.com/shaoshuai0102)<br/>|[<img src="https://avatars.githubusercontent.com/u/5856440?v=4" width="100px;"/><br/><sub><b>whxaxes</b></sub>](https://github.com/whxaxes)<br/>|
| :---: | :---: | :---: | :---: | :---: | :---: |
|[<img src="https://avatars.githubusercontent.com/u/227713?v=4" width="100px;"/><br/><sub><b>atian25</b></sub>](https://github.com/atian25)<br/>|[<img src="https://avatars.githubusercontent.com/u/19343?v=4" width="100px;"/><br/><sub><b>ai</b></sub>](https://github.com/ai)<br/>|[<img src="https://avatars.githubusercontent.com/u/4996660?v=4" width="100px;"/><br/><sub><b>Anemone95</b></sub>](https://github.com/Anemone95)<br/>|[<img src="https://avatars.githubusercontent.com/u/7298095?v=4" width="100px;"/><br/><sub><b>guoshencheng</b></sub>](https://github.com/guoshencheng)<br/>|[<img src="https://avatars.githubusercontent.com/u/27910496?v=4" width="100px;"/><br/><sub><b>p0sec</b></sub>](https://github.com/p0sec)<br/>|[<img src="https://avatars.githubusercontent.com/u/5009418?v=4" width="100px;"/><br/><sub><b>pusongyang</b></sub>](https://github.com/pusongyang)<br/>|
[<img src="https://avatars.githubusercontent.com/u/9857273?v=4" width="100px;"/><br/><sub><b>ShadyZOZ</b></sub>](https://github.com/ShadyZOZ)<br/>|[<img src="https://avatars.githubusercontent.com/u/5064777?v=4" width="100px;"/><br/><sub><b>viko16</b></sub>](https://github.com/viko16)<br/>|[<img src="https://avatars.githubusercontent.com/u/12656301?v=4" width="100px;"/><br/><sub><b>brizer</b></sub>](https://github.com/brizer)<br/>|[<img src="https://avatars.githubusercontent.com/u/7480584?v=4" width="100px;"/><br/><sub><b>EliYao</b></sub>](https://github.com/EliYao)<br/>
[<img src="https://avatars.githubusercontent.com/u/9857273?v=4" width="100px;"/><br/><sub><b>ShadyZOZ</b></sub>](https://github.com/ShadyZOZ)<br/>|[<img src="https://avatars.githubusercontent.com/u/5064777?v=4" width="100px;"/><br/><sub><b>viko16</b></sub>](https://github.com/viko16)<br/>|[<img src="https://avatars.githubusercontent.com/u/12656301?v=4" width="100px;"/><br/><sub><b>brizer</b></sub>](https://github.com/brizer)<br/>|[<img src="https://avatars.githubusercontent.com/u/18703255?v=4" width="100px;"/><br/><sub><b>damujiangr</b></sub>](https://github.com/damujiangr)<br/>|[<img src="https://avatars.githubusercontent.com/u/7480584?v=4" width="100px;"/><br/><sub><b>EliYao</b></sub>](https://github.com/EliYao)<br/>

This project follows the git-contributor [spec](https://github.com/xudafeng/git-contributor), auto updated at `Tue Apr 05 2022 11:54:38 GMT+0800`.
This project follows the git-contributor [spec](https://github.com/xudafeng/git-contributor), auto updated at `Wed May 10 2023 16:36:13 GMT+0800`.

<!-- GITCONTRIBUTOR_END -->

Expand Down
40 changes: 19 additions & 21 deletions README.zh-CN.md
Expand Up @@ -123,10 +123,10 @@ ctoken 从 cookie 中获取

__安全开发者约定__

- `ctx.ctoken` 获取 ctoken 的逻辑。使用者不要调用,安全插件内部使用。
- `ctx.setCTOKEN()` 设置 ctoken 的逻辑。使用者不要调用,安全插件内部使用。
- `ctx.assertCTOKEN()` ctoken 校验逻辑。使用者不要调用,安全插件内部使用。
- `ctx.setCTOKEN()`会将cookie设置到主域名下,主要考虑主域名下其他子域名对应的应用之间的互相调用。例如 A.xx.com 域种了 ctoken,会设置cookie到xx.com域上,在 B.xx.com 域的时候可以利用 ctoken 去请求,在 A 域 jsonp 请求 B 域的时候,B 域也可以验证 ctoken。
* `ctx.ctoken` 获取 ctoken 的逻辑。使用者不要调用,安全插件内部使用。
* `ctx.setCTOKEN()` 设置 ctoken 的逻辑。使用者不要调用,安全插件内部使用。
* `ctx.assertCTOKEN()` ctoken 校验逻辑。使用者不要调用,安全插件内部使用。
* `ctx.setCTOKEN()`会将cookie设置到主域名下,主要考虑主域名下其他子域名对应的应用之间的互相调用。例如 A.xx.com 域种了 ctoken,会设置cookie到xx.com域上,在 B.xx.com 域的时候可以利用 ctoken 去请求,在 A 域 jsonp 请求 B 域的时候,B 域也可以验证 ctoken。

可拓展实现。例如 ctoken token 存在什么 cookie,存什么字段等,都可以通过以上两个接口拓展。

Expand Down Expand Up @@ -206,7 +206,7 @@ url 过滤。

对模板中要输出的变量,加 `helper.surl($value)`

**特别需要注意的是在需要解析url的地方,surl 外面一定要加上双引号,否则就会导致XSS漏洞。**
__特别需要注意的是在需要解析url的地方,surl 外面一定要加上双引号,否则就会导致XSS漏洞。__

不使用 surl

Expand Down Expand Up @@ -254,7 +254,7 @@ console.log(`var foo = "${this.helper.sjs(foo)}";`);
将富文本(包含 html 代码的文本)当成变量直接在模版里面输出时,需要用到 shtml 来处理。
使用 shtml 可以输出 html 的 tag,同时执行 xss 的过滤动作,过滤掉非法的脚本。

** 由于是一个非常复杂的安全处理过程,对服务器处理性能一定影响,如果不是输出 HTML,请勿使用。**
**由于是一个非常复杂的安全处理过程,对服务器处理性能一定影响,如果不是输出 HTML,请勿使用。**

简单示例:

Expand All @@ -273,8 +273,8 @@ const value = `<a href="http://www.domain.com">google</a><script>evilcode…</sc

shtml 在 [xss](https://github.com/leizongmin/js-xss/) 模块基础上增加了针对域名的过滤。

- [默认规则](https://github.com/leizongmin/js-xss/blob/master/lib/default.js)
- 自定义过滤项 http://jsxss.com/zh/options.html
* [默认规则](https://github.com/leizongmin/js-xss/blob/master/lib/default.js)
* 自定义过滤项 <http://jsxss.com/zh/options.html>

例如只支持 a 标签,且除了 title 其他属性都过滤掉:

Expand Down Expand Up @@ -311,9 +311,9 @@ ${helper.shtml($html)}

不合法的路径包括:

- 使用 `..` 的相对路径
- 使用 `/` 开头的绝对路径
- 以及以上试图通过 url encode 试图绕过校验的结果字符串
* 使用 `..` 的相对路径
* 使用 `/` 开头的绝对路径
* 以及以上试图通过 url encode 试图绕过校验的结果字符串

```js
const foo = '/usr/local/bin';
Expand All @@ -328,7 +328,7 @@ json转义
在js中输出json,若未做转义,易被利用为xss漏洞。提供此宏做json encode,会遍历json中的key,将value的值中,所有非白名单字符转义为\x形式,防止xss攻击。同时保持json结构不变。
若你有模板中输出一个json字符串给js应用的场景,请使用 `${this.helper.sjson(变量名)}`进行转义。

**处理过程较复杂,性能损耗较大,尽量避免使用**
__处理过程较复杂,性能损耗较大,尽量避免使用__

实例:

Expand Down Expand Up @@ -368,7 +368,6 @@ json转义

命令行参数转义。给字符串增加一对单引号并且能引用或者转码任何已经存在的单引号, 这样以确保能够直接将一个字符串传入 shell 函数,并且还是确保安全的。


```js
const ip = '127.0.0.1 && cat /etc/passwd'
const cmd = 'ping -c 1 ' + this.helper.escapeShellArg(ip);
Expand All @@ -381,7 +380,6 @@ console.log(cmd);

命令行转义,从输入的命令行中删除下列字符: ```#&;`|*?~<>^()[]{}$;'", 0x0A 和 0xFF```


```js
const ip = '127.0.0.1 && cat /etc/passwd'
const cmd = 'ping -c 1 ' + this.helper.escapeShellCmd(ip);
Expand All @@ -396,14 +394,14 @@ console.log(cmd);

默认开启,如果是 http 站点,需要关闭

- maxAge 默认一年 `365 * 24 * 3600`
- includeSubdomains 默认 false
* maxAge 默认一年 `365 * 24 * 3600`
* includeSubdomains 默认 false

### csp

默认关闭。需要开启的话,需要和安全工程师确定开启策略。

- policy 策略
* policy 策略

### X-Download-Options:noopen

Expand All @@ -417,11 +415,11 @@ console.log(cmd);

默认 SAMEORIGIN,只允许同域把本页面当作 iframe 嵌入。

- value 默认值 `SAMEORIGIN`
* value 默认值 `SAMEORIGIN`

### X-XSS-Protection

- close 默认值false,即设置为 `1; mode=block`
* close 默认值false,即设置为 `1; mode=block`

## 其他

Expand All @@ -435,9 +433,9 @@ console.log(cmd);
|[<img src="https://avatars.githubusercontent.com/u/985607?v=4" width="100px;"/><br/><sub><b>dead-horse</b></sub>](https://github.com/dead-horse)<br/>|[<img src="https://avatars.githubusercontent.com/u/156269?v=4" width="100px;"/><br/><sub><b>fengmk2</b></sub>](https://github.com/fengmk2)<br/>|[<img src="https://avatars.githubusercontent.com/u/893152?v=4" width="100px;"/><br/><sub><b>jtyjty99999</b></sub>](https://github.com/jtyjty99999)<br/>|[<img src="https://avatars.githubusercontent.com/u/360661?v=4" width="100px;"/><br/><sub><b>popomore</b></sub>](https://github.com/popomore)<br/>|[<img src="https://avatars.githubusercontent.com/u/456108?v=4" width="100px;"/><br/><sub><b>shaoshuai0102</b></sub>](https://github.com/shaoshuai0102)<br/>|[<img src="https://avatars.githubusercontent.com/u/5856440?v=4" width="100px;"/><br/><sub><b>whxaxes</b></sub>](https://github.com/whxaxes)<br/>|
| :---: | :---: | :---: | :---: | :---: | :---: |
|[<img src="https://avatars.githubusercontent.com/u/227713?v=4" width="100px;"/><br/><sub><b>atian25</b></sub>](https://github.com/atian25)<br/>|[<img src="https://avatars.githubusercontent.com/u/19343?v=4" width="100px;"/><br/><sub><b>ai</b></sub>](https://github.com/ai)<br/>|[<img src="https://avatars.githubusercontent.com/u/4996660?v=4" width="100px;"/><br/><sub><b>Anemone95</b></sub>](https://github.com/Anemone95)<br/>|[<img src="https://avatars.githubusercontent.com/u/7298095?v=4" width="100px;"/><br/><sub><b>guoshencheng</b></sub>](https://github.com/guoshencheng)<br/>|[<img src="https://avatars.githubusercontent.com/u/27910496?v=4" width="100px;"/><br/><sub><b>p0sec</b></sub>](https://github.com/p0sec)<br/>|[<img src="https://avatars.githubusercontent.com/u/5009418?v=4" width="100px;"/><br/><sub><b>pusongyang</b></sub>](https://github.com/pusongyang)<br/>|
[<img src="https://avatars.githubusercontent.com/u/9857273?v=4" width="100px;"/><br/><sub><b>ShadyZOZ</b></sub>](https://github.com/ShadyZOZ)<br/>|[<img src="https://avatars.githubusercontent.com/u/5064777?v=4" width="100px;"/><br/><sub><b>viko16</b></sub>](https://github.com/viko16)<br/>|[<img src="https://avatars.githubusercontent.com/u/12656301?v=4" width="100px;"/><br/><sub><b>brizer</b></sub>](https://github.com/brizer)<br/>|[<img src="https://avatars.githubusercontent.com/u/7480584?v=4" width="100px;"/><br/><sub><b>EliYao</b></sub>](https://github.com/EliYao)<br/>
[<img src="https://avatars.githubusercontent.com/u/9857273?v=4" width="100px;"/><br/><sub><b>ShadyZOZ</b></sub>](https://github.com/ShadyZOZ)<br/>|[<img src="https://avatars.githubusercontent.com/u/5064777?v=4" width="100px;"/><br/><sub><b>viko16</b></sub>](https://github.com/viko16)<br/>|[<img src="https://avatars.githubusercontent.com/u/12656301?v=4" width="100px;"/><br/><sub><b>brizer</b></sub>](https://github.com/brizer)<br/>|[<img src="https://avatars.githubusercontent.com/u/18703255?v=4" width="100px;"/><br/><sub><b>damujiangr</b></sub>](https://github.com/damujiangr)<br/>|[<img src="https://avatars.githubusercontent.com/u/7480584?v=4" width="100px;"/><br/><sub><b>EliYao</b></sub>](https://github.com/EliYao)<br/>

This project follows the git-contributor [spec](https://github.com/xudafeng/git-contributor), auto updated at `Tue Apr 05 2022 11:54:38 GMT+0800`.
This project follows the git-contributor [spec](https://github.com/xudafeng/git-contributor), auto updated at `Wed May 10 2023 16:36:13 GMT+0800`.

<!-- GITCONTRIBUTOR_END -->

Expand Down
4 changes: 1 addition & 3 deletions app.js
@@ -1,8 +1,6 @@
'use strict';

const assert = require('node:assert');
const safeRedirect = require('./lib/safe_redirect');
const utils = require('./lib/utils');
const assert = require('assert');

module.exports = app => {
app.config.coreMiddleware.push('securities');
Expand Down
9 changes: 4 additions & 5 deletions app/extend/context.js
@@ -1,10 +1,9 @@
'use strict';

const safeCurl = require('../../lib/extend/safe_curl');
const isSafeDomainUtil = require('../../lib/utils').isSafeDomain;
const nanoid = require('nanoid/non-secure').nanoid;
const debug = require('node:util').debuglog('egg-security:context');
const { nanoid } = require('nanoid/non-secure');
const Tokens = require('csrf');
const debug = require('debug')('egg-security:context');
const safeCurl = require('../../lib/extend/safe_curl');
const utils = require('../../lib/utils');

const tokens = new Tokens();
Expand Down Expand Up @@ -44,7 +43,7 @@ module.exports = {
*/
isSafeDomain(domain) {
const domainWhiteList = this.app.config.security.domainWhiteList;
return isSafeDomainUtil(domain, domainWhiteList);
return utils.isSafeDomain(domain, domainWhiteList);
},

// Add nonce, random characters will be OK.
Expand Down
6 changes: 2 additions & 4 deletions app/middleware/securities.js
@@ -1,8 +1,6 @@
'use strict';

const path = require('node:path');
const assert = require('node:assert');
const compose = require('koa-compose');
const path = require('path');
const assert = require('assert');
const createMatch = require('egg-path-matching');

module.exports = (_, app) => {
Expand Down
4 changes: 1 addition & 3 deletions lib/middlewares/csrf.js
@@ -1,6 +1,4 @@
'use strict';

const debug = require('debug')('egg-security:csrf');
const debug = require('node:util').debuglog('egg-security:csrf');
const typeis = require('type-is');
const utils = require('../utils');

Expand Down

0 comments on commit c3ca817

Please sign in to comment.