如何防范直接访问AJAX/JSON API时出现的XSS攻击?
首先得明确:你当前的做法——服务器返回未转义的原始JSON(保证业务逻辑正确性)、客户端渲染前转义数据(防范XSS)——本身是合理的。现在要解决的是用户直接访问API链接时的XSS风险,主要可以从以下几个维度处理:
1. 强制设置正确的Content-Type响应头
这是最核心的防护手段。给你的JSON API响应设置Content-Type: application/json,而不是text/html或者其他可能被浏览器当作HTML解析的类型。
浏览器的安全机制会识别这个头,将响应内容当作纯文本/JSON数据处理,不会尝试解析成HTML或执行其中的脚本,从根源上避免XSS触发。
注意:一定要确保服务器没有错误地覆盖这个头,比如某些后端框架可能默认返回text/html,需要手动配置修改。
2. 添加X-Content-Type-Options: nosniff响应头
这个头可以强制浏览器严格遵守你设置的Content-Type,禁止它进行MIME类型嗅探。有些旧浏览器或者特殊场景下,浏览器可能会忽略Content-Type,尝试根据内容猜测类型(比如如果JSON里包含类似HTML的字符串,可能被误判),添加这个头就能杜绝这种情况,进一步强化安全。
3. 给JSON响应添加安全前缀(防范XSSI攻击)
如果你的API返回的JSON可能被攻击者通过<script>标签加载(比如用来窃取用户数据的XSSI攻击),可以在JSON内容的最开头添加一个无效的JavaScript前缀,比如:
)]}',\n
这样即使浏览器错误地将JSON当作脚本解析,这个前缀会让脚本语法报错,无法执行,也就无法窃取数据。这种方式被很多平台采用,是一种额外的安全加固手段。
关于CSRF令牌的说明
CSRF令牌主要是用来防范跨站请求伪造(攻击者诱导用户在已登录状态下向你的服务器发送恶意请求),而你当前的问题是用户直接访问API链接时的XSS风险,所以CSRF令牌并不是解决这个问题的核心方案。除非你的API的GET请求包含敏感操作(不符合REST规范,GET应该是只读、安全的),否则不需要用CSRF来处理这个场景。
总结
优先级最高的是设置Content-Type: application/json和X-Content-Type-Options: nosniff,这两个措施就能解决绝大多数直接访问API的XSS风险。在此基础上,可以添加安全前缀作为额外防护,确保万无一失。
内容的提问来源于stack exchange,提问作者Joshua Fox

