Ninety-nine Pitchers of Malt

    @58fe/hammer-security

    0.1.1 • Public • Published

    hammer-security

    Build Status codecov

    hammer的安全模块


    目录结构

    ├── config
    │   └── index.js
    ├── lib
    │   ├── header
    │   │   ├── hsts.js
    │   │   ├── methodnoallow.js
    │   │   ├── noopen.js
    │   │   ├── nosniff.js
    │   │   ├── referrerPolicy.js
    │   │   ├── xframe.js
    │   │   └── xssProtection.js
    │   ├── helper
    │   │   ├── csrf.js
    │   │   ├── escape.js
    │   │   ├── index.js
    │   │   ├── scli.js
    │   │   ├── shtml.js
    │   │   ├── sjs.js
    │   │   ├── sjson.js
    │   │   ├── spath.js
    │   │   └── surl.js
    │   └── utils.js
    └── test
        ├── lib
        │   ├── header
        │   │   ├── hsts.test.js
        │   │   ├── methodnoallow.test.js
        │   │   ├── noopen.test.js
        │   │   ├── nosniff.test.js
        │   │   ├── referrerPolicy.test.js
        │   │   ├── xframe.test.js
        │   │   └── xssProtection.test.js
        │   ├── helper
        │   │   ├── scli.test.js
        │   │   ├── sjson.test.js
        │   │   ├── shtml.test.js
        │   │   ├── sjs.test.js
        │   │   ├── spath.test.js
        │   │   └── surl.test.js
        │   └── utils.test.js
        └── utils
            └── app.js

    Helper

    csrf

    接入csrf 模块, 具体使用方法请看github

    .surl()

    url 过滤。

    用于在html标签中中要解析 url 的地方(比如 <a href=""/><img src=""/>),其他地方不允许使用。

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

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

    不使用 surl

    <a href="$value" />

    output:

    <a href="http://www.domain.com<script>" />

    使用 surl

    <a href="helper.surl($value)" />

    output:

    <a href="http://www.domain.com&lt;script&gt;" />

    .escape()

    对字符串进行 xss 过滤,安全性最高的过滤方式。

    const str = '><script>alert("abc") </script><';
    console.log(helper.escape(str));
    // => &gt;&lt;script&gt;alert(&quot;abc&quot;) &lt;/script&gt;&lt;

    .sjs()

    用于在 js(包括 onload 等 event)中输出变量,会对变量中字符进行 JAVASCRIPT ENCODE, 将所有非白名单字符转义为 \x spath形式,防止xss攻击,也确保在 js 中输出的正确性。

    const foo = '"hello"';
    
    // 未使用 sjs
    console.log(`var foo = "${foo}";`);
    // => var foo = ""hello"";
    
    // 使用 sjs
    console.log(`var foo = "${helper.sjs(foo)}";`);
    // => var foo = "\\x22hello\\x22";

    .shtml()

    将富文本(包含 html 代码的文本)当成变量直接在模版里面输出时,需要用到 shtml 来处理。 使用 shtml 可以输出 html 的 tag,同时执行 xss 的过滤动作,过滤掉非法的脚本。

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

    简单示例:

    // js
    const value = `<a href="http://www.domain.com">google</a><script>evilcode…</script>`;
    
    // 模板
    <html>
    <body>
      ${helper.shtml(value)}
    </body>
    </html>
    
    // 输出
    '<a href="http://www.domain.com">google</a>&lt;script&gt;evilcode…&lt;/script&gt;'

    shtml 在 xss 模块基础上实现的。

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

    const html = '<a href="http://www.domain.com" title="test" onClick="hello()"></a>';
    const options = {
      whiteList: {
        a: [ 'href', 'title' ],
      },
    };
    // html
    ${helper.shtml(html, options)}
    
    // 输出
    '<a href="http://www.domain.com" title="test"></a>'

    注意,shtml 使用了严格的白名单机制,除了过滤掉 xss 风险的字符串外, 在 默认规则 外的 tag 和 attr 都会被过滤掉。

    例如 html 标签就不在白名单中,

    const html = '<html></html>';
    const options = {
      whiteList: {
        a: [ 'href', 'title' ],
      },
    };
    // html
    ${helper.shtml(html, options)}
    
    // 输出
    '&lt;html&gt;&lt;/html&gt;'

    常见的 data-xx 属性由于不在白名单中,所以都会被过滤。

    所以,一定要注意 shtml 的适用场景,一般是针对来自用户的富文本输入,切忌滥用,功能既受到限制,又会影响服务端性能。 此类场景一般是论坛、评论系统等,即便是论坛等如果不支持 html 内容输入,也不要使用此 helper,直接使用 escape 即可。

    .spath()

    如果把输入字符串用作 path 路径,需要使用 spath 进行安全检验。若路径不合法,返回 null。

    不合法的路径包括:

    • 使用 .. 的相对路径
    • 使用 / 开头的绝对路径
    • 以及以上试图通过 url encode 试图绕过校验的结果字符串
    const foo1 = '/usr/local/bin';
    const foo2 = '../local/bin';
    
    console.log(helper.spath(foo1));
    console.log(helper.spath(foo2));
    
    // => null
    // => null

    .sjson()

    json转义

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

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

    实例:

      <script>
        window.locals = ${helper.sjson(locals)};
      </script>

    .scli()

    远程命令执行漏洞,用户通过浏览器提交执行命令,由于服务器端没有针对执行函数做过滤,导致可以执行命令,通常可导致入侵服务器。

    如果用户可控变量为命令中的参数。则直接使用安全包函数过滤。

    修复前:

      cp.exec("bash /home/admin/xxx/run.sh " + port);

    修复后:

      cp.exec("bash /home/admin/xxx/run.sh " + helper.scli(port));

    如果因为业务需要,需要在参数中天加白名单之外的字符。可以将用户输入按照该字符分割,并使用过滤函数过滤每一段数据。

    如果用户可控变量为命令中的命令,则和开发协商修改功能或功能下线。

    Web 安全头

    hsts(Strict-Transport-Security)

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

    • maxAge 默认一年 365 * 24 * 3600
    • includeSubdomains 默认 false

    使用方法:

    app.use(hsts(options))

    X-Download-Options:noopen

    默认开启,禁用IE下下载框Open按钮,防止 ie 下下载文件默认被打开 xss

    使用方法:

    app.use(noopen())

    X-Content-Type-Options:nosniff

    禁用 IE8 自动嗅探 mime 功能。例如:text/plain 却当成 text/html 渲染,特别当本站点服务内容未必可信的时候。

    使用方法:

    app.use(nosniff())

    Referrer-Policy

    当用户在浏览器上点击一个链接时,会产生一个 HTTP 请求,用于获取新的页面内容,而在该请求的报头中,会包含一个 Referrer,用以指定该请求是从哪个页面跳转页来的,常被用于分析用户来源等信息。但是也有成为用户的一个不安全因素,比如有些网站直接将 sessionid 或是 token 放在地址栏里传递的,会原样不动地当作 Referrer 报头的内容传递给第三方网站。

    所以就有了 Referrer Policy,用于过滤 Referrer 报头内容,目前是一个候选标准,不过已经有部分浏览器支持该标准。

    指令值 目前包含了以下几种指令值:

    enum ReferrerPolicy {
      "",
      "no-referrer",
      "no-referrer-when-downgrade",
      "same-origin",
      "origin",
      "strict-origin",
      "origin-when-cross-origin",
      "strict-origin-when-cross-origin",
      "unsafe-url"
    };

    使用方法:

    app.use(nosniff(options))

    X-Frame-Options

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

    • value 默认值 SAMEORIGIN

    使用方法:

    app.use(xframe(options))

    X-XSS-Protection

    • close 默认值false,即设置为 1; mode=block

    使用方法:

    app.use(xssProtection(options))

    其他

    • 禁止 trace track 两种类型请求

      使用方法:

      app.use(notAllow())

    License

    MIT

    Install

    npm i @58fe/hammer-security

    DownloadsWeekly Downloads

    4

    Version

    0.1.1

    License

    MIT

    Unpacked Size

    41.7 kB

    Total Files

    42

    Last publish

    Collaborators

    • skybjf
    • rockolin
    • reking
    • imlimiao
    • xiaoyuya
    • felix_xue
    • zhangboyu
    • marinamumu
    • bestvist
    • liuhanbing