阅读(290) (0)

Node.js 响应输出

2021-06-01 09:52:13 更新

1.6.1 【必须】设置正确的HTTP响应包类型

  • 响应头 Content-Type 与实际响应内容,应保持一致。如:API 响应数据类型是 json,则响应头使用application/json;若为 xml,则设置为text/xml

1.6.2 【必须】添加安全响应头

  • 所有接口、页面,添加响应头 X-Content-Type-Options: nosniff
  • 所有接口、页面,添加响应头X-Frame-Options。按需合理设置其允许范围,包括:DENYSAMEORIGINALLOW-FROM origin。用法参考:MDN文档
  • 推荐使用组件: helmet

1.6.3 【必须】外部输入拼接到响应页面前,进行编码处理

场景 编码规则
输出点在 HTML 标签之间 需要对以下 6 个特殊字符进行 HTML 实体编码(&<>"',/)。
示例:
& --> `&amp;
< --> &lt;
>--> &gt;
" --> &quot;
' --> &#x27;  
/ --> &#x2F;
输出点在 HTML 标签普通属性内(如 href、src、style 等,on 事件除外) 要对数据进行 HTML 属性编码。
编码规则:除了阿拉伯数字和字母,对其他所有的字符进行编码,只要该字符的 ASCII 码小于 256。编码后输出的格式为&#xHH;(以&#x开头,HH则是指该字符对应的十六进制数字,分号作为结束符)
输出点在 JS 内的数据中 需要进行 js 编码
编码规则:
除了阿拉伯数字和字母,对其他所有的字符进行编码,只要该字符的 ASCII 码小于 256。编码后输出的格式为 \xHH (以 \x 开头,HH 则是指该字符对应的十六进制数字)
Tips:这种场景仅限于外部数据拼接在 js 里被引号括起来的变量值中。除此之外禁止直接将代码拼接在 js 代码中。
输出点在 CSS 中(Style 属性) 需要进行 CSS 编码
编码规则:
除了阿拉伯数字和字母,对其他所有的字符进行编码,只要该字符的 ASCII 码小于 256。编码后输出的格式为 \HH (以 \ 开头,HH则是指该字符对应的十六进制数字)
输出点在 URL 属性中 对这些数据进行 URL 编码
Tips:除此之外,所有链接类属性应该校验其协议。禁止 JavaScript、data 和 Vb 伪协议。

1.6.4 【必须】响应禁止展示物理资源、程序内部代码逻辑等敏感信息

  • 业务生产(正式)环境,应用异常时,响应内容禁止展示敏感信息。包括但不限于:物理路径程序内部源代码调试日志内部账号名内网ip地址等。

// bad
Access denied for user 'xxx'@'xx.xxx.xxx.162' (using password: NO)"

1.6.5 【推荐】添加安全纵深防御措施

  • 部署 CSP,规则中应引入最新的严格模式特性nonce-

// good:使用helmet组件安全地配置响应头
const express = require("express");
const helmet = require("helmet");
const app = express();
app.use(helmet());


// good:正确配置Content-Type、添加了安全响应头,引入了CSP
Router.get("/", (req, res) => {
    res.header("Content-Type", "application/json");
    res.header("X-Content-Type-Options", "nosniff");
    res.header("X-Frame-Options", "SAMEORIGIN");
    res.header("Content-Security-Policy", "script-src 'self'");
});

关联漏洞:中风险 - XSS、中风险 - 跳转漏洞