我最近收到来自第三方的建议,“出于安全原因”在所有服务器响应中编码 HTML 特殊字符。所以:
' --> '
& --> &
例如
{ "id": 1, "name": "Miles O'Brien" }
问题:这样做是否有安全收益,还是只是一种偏执狂?
我最近收到来自第三方的建议,“出于安全原因”在所有服务器响应中编码 HTML 特殊字符。所以:
' --> '
& --> &
例如
{ "id": 1, "name": "Miles O'Brien" }
问题:这样做是否有安全收益,还是只是一种偏执狂?
& --> &
你确定这是他们想要的那种编码吗?
对在 JSON 响应中返回的 HTML 特殊字符进行编码是有原因的,这是为了避免由不需要的类型嗅探引起的 XSS。例如,如果您有:
{ "name": "<body>Mister <script>...</script>" }
并且攻击者在 HTML 上下文(例如 iframe src)中包含指向您的 JSON 返回资源的链接,然后愚蠢的浏览器可能会认为,由于赠品字符串<body>
,您的文档不是 JSON 对象,而是 HTML 文档。然后它可以在您的安全上下文中执行脚本,从而导致 XSS 漏洞。
对此的解决方案是使用 JSON 字符串文字转义,例如:
{ "name": "\u003Cbody\u003EMister \u003Cscript\u003E...\u003C/script\u003E" }
在这种情况下使用 HTML 转义虽然可以避免问题,但会产生改变字符串含义的副作用。"Miles O'Brien"
JSON 解析器读取的仍然是 &x-twenty-7,所以如果你使用jQuery 或 jQuery之类的Miles O'Brien
方法将该值写入页面.value
,它看起来会很奇怪。.textContent
.text()
现在,如果您将该字符串分配给.innerHTML
jQuery .html()
,那么是的,您肯定需要在某个时候对其进行 HTML 转义,而不管 JSON XSS 问题如何。但是,我建议在这种情况下,出于关注点分离的原因,该点应该在您实际将内容注入 HTML 标记的客户端,而不是生成 JSON 的服务器端。一般来说,当有更安全的 DOM 风格的方法可用时,最好避免将字符串注入标记。
根据您使用数据的目的,是的,有安全优势。
如果您正在接受用户输入,并将其发送回您的服务器,然后使用它与您的数据库进行交互;我可能会终止您的一个字符串,并注入我自己的 SQL 语句。即使没有恶意,您发送引号字符也可能会意外终止字符串。
似乎有一种趋势是保护新手/愚蠢/天真的开发人员不会在他们的网站上创建 XSS 漏洞。尤其是当其他人要处理这些响应时(例如,开放 API,您团队中的一些初级开发人员),他可能会忘记在将字符串提供给某个$('#myelement).html()
方法之前正确地对字符串进行 HTML 编码。这个想法是,在服务器上转义这些响应将导致对不了解转义的开发人员进行双重转义(最坏的情况),而“聪明”的开发人员将知道何时在使用它们之前对值进行转义。另一种选择是“不太聪明”的开发人员将创建一个充满 XSS 安全漏洞的站点。
就我个人而言,我不是这种趋势的忠实拥护者,但我当然看到它将如何使整个互联网变得更安全,尤其是随着 Web 开发越来越多地被作为一种爱好来实践......你选择做的是对你来说,但这是请求对 JSON 中的所有字符串进行 html 转义的原因。
其他人这样做的例子: