Skip to content

Commit

Permalink
feat: add rotateWhenInvalid option for CSRF token (#98)
Browse files Browse the repository at this point in the history
closes #97

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced a new security option `rotateWhenInvalid` to control CSRF
token rotation when invalid, enhancing overall security.

- **Documentation**
- Updated `README.md` and `README.zh-CN.md` to include the new
`rotateWhenInvalid` configuration option.

- **Tests**
- Added test cases to verify CSRF token rotation behavior when
`rotateWhenInvalid` is enabled.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
  • Loading branch information
hongzzz committed Jul 3, 2024
1 parent 4711437 commit ae37c8f
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ exports.security = {
headerName: 'x-csrf-token', // request csrf token's name in header
bodyName: '_csrf', // request csrf token's name in body
queryName: '_csrf', // request csrf token's name in query
rotateWhenInvalid: false, // rotate csrf secret when csrf token invalid. For multi applications which be deployed on the same domain, as tokens from one application may impact others.
refererWhiteList: [], // referer white list
supportedRequests: [ // supported URL path and method, the package will match URL path regex patterns one by one until path matched. We recommend you set {path: /^\//, methods:['POST','PATCH','DELETE','PUT','CONNECT']} as the last rule in the list, which is also the default config.
{path: /^\//, methods:['POST','PATCH','DELETE','PUT','CONNECT']}
Expand Down
1 change: 1 addition & 0 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ exports.security = {
headerName: 'x-csrf-token', // csrf token 在 header 中的名称
bodyName: '_csrf', // csrf token 在 body 中的名称
queryName: '_csrf', // csrf token 在 query 中的名称
rotateWhenInvalid: false, // csrf invalid 时刷新 token,用于同域名下多个业务 token 可能互相影响的情况
refererWhiteList: [], // referer 白名单
supportedRequests: [ // 支持的 url path pattern 和方法,根据配置名单由上至下匹配 url path 正则,建议在自定义时配置 {path: /^\//, methods:['POST','PATCH','DELETE','PUT','CONNECT']} 为兜底规则
{path: /^\//, methods:['POST','PATCH','DELETE','PUT','CONNECT']},
Expand Down
4 changes: 4 additions & 0 deletions app/extend/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,10 @@ module.exports = {
if (token !== this[CSRF_SECRET] && !tokens.verify(this[CSRF_SECRET], token)) {
debug('verify secret and token error');
this[LOG_CSRF_NOTICE]('invalid csrf token');
const { rotateWhenInvalid } = this.app.config.security.csrf;
if (rotateWhenInvalid) {
this.rotateCsrfSecret();
}
return 'invalid csrf token';
}
},
Expand Down
1 change: 1 addition & 0 deletions config/config.default.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ module.exports = () => {
headerName: 'x-csrf-token',
bodyName: '_csrf',
queryName: '_csrf',
rotateWhenInvalid: false,
supportedRequests: [
{ path: /^\//, methods: [ 'POST', 'PATCH', 'DELETE', 'PUT', 'CONNECT' ] },
],
Expand Down
11 changes: 11 additions & 0 deletions test/csrf.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,17 @@ describe('test/csrf.test.js', () => {
});
});

it('token should be rotated when enable rotateWhenInvalid', async () => {
mm(app.config.security.csrf, 'rotateWhenInvalid', true);
await app.httpRequest()
.post('/update')
.set('x-csrf-token', '2')
.set('cookie', 'csrfToken=1')
.send({ title: 'invalid token' })
.expect(403)
.expect(res => assert(!!res.header['set-cookie']));
});

it('should show deprecate message if ignoreJSON = true', async () => {
const app = mm.app({ baseDir: 'apps/csrf-ignorejson' });
await app.ready();
Expand Down

0 comments on commit ae37c8f

Please sign in to comment.