Package Exports
- egg-security
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (egg-security) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
egg-security
Security plugin in egg
Egg's default security plugin, generally no need to configure.
Install
$ npm i egg-securityUsage & configuration
config.default.js
exports.security = {
xframe: {
value: 'SAMEORIGIN',
},
};Disable security precautions
If you want to disable some security precautions, set enable porperty to 'false' directly.
For example, disable xframe defense:
exports.security = {
xframe: {
enable: false,
},
};match & ignore
If you want to set security config open for a certain path, you can configure match option.
For example, just open csp when path contains /example, you can configure with the following configuration:
exports.security = {
csp: {
match: '/example',
policy: {
//...
},
},
};
If you want to set security config disable for a certain path, you can configure match option.
For example, just disable xframe when path contains /example while our pages can be embedded in cooperative businesses , you can configure with the following configuration:
exports.security = {
csp: {
ignore: '/example',
xframe: {
//...
},
},
};
mention:match has higher priority than ignore
Dynamic configuration for security plugins depend on context
There are times when we want to be more flexible to configure security plugins.For example:
- To decide whether to enable or disable the xframe security header from the context of the request.
- To decide csp policies from different request urls.
Then we can configure this.securityOptions[name] opts in the custom middleware or controller,then the current request configuration will overrides the default configuration (new configuration will be merged and override the default project configuration, but only take effect in the current request)
function*() {
// if satisfied some condition
// change configuration
this.securityOptions.xframe = {
value: 'ALLOW-FROM: https://alipay.com',
};
// disable configuration
this.securityOptions.xssProtection = {
enable: false,
}
}Not all security plugins support dynamic configuration, only following plugins list support
- csp
- hsts
- noopen
- nosniff
- xframe
- xssProtection
And in helper:
- shtml
helper is the same way to configure.
this.securityOptions.shtml = {
whiteList: {
},
};Mention
- Security is a big thing, please pay attention to the risk of changes in the security configuration (especially dynamic changes)
this.securityOptionsthe current request configuration will overrides the default configuration, but it does not make a deep copy,so pay attention to configurecsp.policy, it will not be merged.- If you configure
this.securityOptions,please write unit tests to ensure the code is correct.
API
ctx.isSafeDomain(domain)
Whether or not the domain is in the whitelist of the configuration. See ctx.redirect.
Note: egg-cors module uses this function internally to determine whether or not send back an Access-Control-Allow-Origin response header with the value of safe domain. Otherwise, ignore the request with an error, No 'Access-Control-Allow-Origin' header is present on the requested resource.
exports.security = {
domainWhiteList: ['http://localhost:4200']
};Interface restriction
csrf
usage
ctx.csrfgetter 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.
Using csrf when upload by formData
browser:
<form method="POST" action="/upload?_csrf={{ ctx.csrf | safe }}" enctype="multipart/form-data">
title: <input name="title" />
file: <input name="file" type="file" />
<button type="submit">上传</button>
</form>ctoken
Prevent cross site attack when request by Ajax.
usage
when request by ajax, use ctoken for parameter name, then put ctoken value. Ctoken value could get from cookie.
developer agreement
ctx.ctokenUsed to access ctoken. Users do not call ,used by plugin itself.ctx.setCTOKEN()Used to set ctoken. Users do not call ,used by plugin itself。ctx.assertCTOKEN()Used to validate ctoken. Users do not call ,used by plugin itself。ctx.setCTOKEN()Used to set cookie under main domain.For example, ifA.xx.comneed to set ctoken, cookie will be set underxx.comdomain. ThenB.xx.comcan request with ctoken. If A domain request to B domain by jsonp, B domain can also validate ctoken.
safe redirect
ctx.redirect(url)If url is not in the configuration of the white list, the redirect will be prohibitedctx.unsafeRedirect(url)Not Recommended;
Security plugin override ctx.redirect method,all redirects will be judged by the domain name.
If you need to use ctx.redirect, you need to do the following configuration in the application configuration file:
exports.security = {
domainWhiteList:['.alipay.com'], // security whitelist, starts with '.'
};If user do not configure domainWhiteList or domainWhiteList is empty, it will pass all redirects, equal to ctx.unsafeRedirect(url)
jsonp
Based on jsonp-body.
Defense:
- The longest callback function name limit of 50 characters.
- Callback function only allows "[","]","a-zA-Z0123456789_", "$" "." to prevent
xssorutf-7attack.
Config:
- callback function default name
_callback. - limit - function name limit, default by 50.
helper
.escape()
String xss filter, the most secure filtering mechanism.
const str = '><script>alert("abc") </script><';
console.log(ctx.helper.escape(str));
// => ><script>alert("abc") </script><In nunjucks template, escape by default.
.surl()
url filter.
Used for url in html tags (like <a href=""/><img src=""/>),please do not call under other places.
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.**
Example: do not use surl
<a href="$value" />output:
<a href="http://ww.alipay.com<script>" />Use surl
<a href="helper.surl($value)" />output:
<a href="http://ww.alipay.com<script>" />.sjs()
Used to output variables in javascript(include onload/event),it will do JAVASCRIPT ENCODE for the variable string.It will escape all characters to \x which are not in the whitelist to avoid XSS attack.
const foo = '"hello"';
// not use sjs
console.log(`var foo = "${foo}";`);
// => var foo = ""hello"";
// use sjs
console.log(`var foo = "${this.helper.sjs(foo)}";`);
// => var foo = "\\x22hello\\x22";.shtml()
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.**
Examples:
// js
const value = `<a href="http://www.alipay.com">alipay</a><script>evilcode…</script>`;
// in your view
<html>
<body>
${helper.shtml($value)}
</body>
</html>
// => <a href="http://www.alipay.com">alipay</a><script>evilcode…</script>shtml based on xss, and add filter by domain feature.
- default rule
- custom rule http://jsxss.com/zh/options.html
For example, only support a tag, and filter all attributes except for title:
whiteList: {a: ['title']}
options:
config.helper.shtml.domainWhiteList: []extends domain whitelist used byhrefandsrcfilter.
Mention that shtml uses a strict white list mechanism, in addition to filtering out the XSS risk of the string,tags and attrs which are not in the default rule will be filtered.
For example html tag is not in the whitelist.
const html = '<html></html>';
// html
${helper.shtml($html)}
// output noneCommonly used data-xx property is not in the whitelist, so it will be filtered.
So please check the applicable scenarios for shtml, it usually used for richtext submmited by user.
A usage error will limit functions, also affect the performance of the server. Such scenes are generally forums, comments, etc.
Even if the forum does not support the HTML content input, do not use this helper, you can directly use escape instead.
.spath()
If you want to use users input for a file path, please use spath for security check. If path is illegal, it will return null.
Illegal path:
- relative path starts with
.. - absolute path starts with
/ - above path try to use
url encodeto bypass the check
const foo = '/usr/local/bin';
console.log(this.helper.spath(foo2));
// => null.sjson()
json encode.
If you want to output json in javascript without encoding, it will be a risk for XSS.
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 ${this.helper.sjson(变量名)}to escape.
it has a very complex process and will lost performance, so avoid the use as far as possible
example:
<script>
window.locals = ${this.helper.sjson(locals)};
</script>.cliFilter()
It will cause remote command execution vulnerability, when user submit the implementation of the command by browser.because the server does not filter for the implementation of the function, resulting in the execution of the command can usually lead to the invasion of the server.
If you want to get user submit for command's parameter, please use cliFilter。
before fix:
cp.exec("bash /home/admin/ali-knowledge-graph-backend/initrun.sh " + port);
after fix:
cp.exec("bash /home/admin/ali-knowledge-graph-backend/initrun.sh " + this.helper.cliFilter(port));
Security Headers
hsts Strict-Transport-Security
Enabled by default. If your website based on http, you should disable it.
- 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
- policy policies used by csp
X-Download-Options:noopen
Default enabled, disable IE download dialog automatically open download file and will cause XSS
X-Content-Type-Options:nosniff
禁用IE8自动嗅探mime功能例如 text/plain 却当成 text/html 渲染,特别当本站点 serve 的内容未必可信的时候。
X-Frame-Options
Defaulting to "SAMEORIGIN", only allow iframe embed by same origin.
- value Defaulting to
SAMEORIGIN
X-XSS-Protection
- disable Defaulting to
false,same as1; mode=block.
Other
- Forbidden
tracetrackoptionshttp method.