AngularJS JSON 漏洞保护未剥离
AngularJS JSON vulnerability protection not stripped
我有一个 angular 应用程序与 Api 进行通信,其中我在 JSON 响应前面加上 angular's official documentation 推荐的 )]}',
数组要做。
问题是,我的浏览器似乎在 angular 之前尝试解码响应。
我已经在调试器中一步步进行了,在 xhr.onload
回调被触发后,响应已经是 null.
我说的代码是这个:
// From angular.js(1.5.9):12122
xhr.onload = function requestLoaded() {
var statusText = xhr.statusText || '';
// responseText is the old-school way of retrieving response (supported by IE9)
// response/responseType properties were introduced in XHR Level2 spec (supported by IE10)
var response = ('response' in xhr) ? xhr.response : xhr.responseText;
// normalize IE9 bug (http://bugs.jquery.com/ticket/1450)
var status = xhr.status === 1223 ? 204 : xhr.status;
// fix status code when it is 0 (0 status is undocumented).
// Occurs when accessing file resources or on Android 4.1 stock browser
// while retrieving files from application cache.
if (status === 0) {
status = response ? 200 : urlResolve(url).protocol === 'file' ? 404 : 0;
}
completeRequest(callback,
status,
response,
xhr.getAllResponseHeaders(),
statusText);
};
}
xhr.response
在 angular 做任何事情之前为空(我认为)。
Angular 尝试使用以下代码去除前缀:
function defaultHttpResponseTransform(data, headers) {
if (isString(data)) {
// Strip json vulnerability protection prefix and trim whitespace
var tempData = data.replace(JSON_PROTECTION_PREFIX, '').trim();
if (tempData) {
var contentType = headers('Content-Type');
if ((contentType && (contentType.indexOf(APPLICATION_JSON) === 0)) || isJsonLike(tempData)) {
data = fromJson(tempData);
}
}
}
return data;
}
但此时数据绝不是字符串,浏览器已经尝试对其进行解码(但失败了)。
Api 的输出如下所示:
)]}',
[{"name": "A"},{"name": "B"}]
如果我删除前缀,它可以正常工作。我试过:
- 歌剧 45.0
- 火狐 46
- Chrome 58
它们的行为都相似,所以我可能遗漏了一些东西。
响应 headers 包含以下内容:
HTTP/1.1 200 OK
Server: nginx/1.11.5
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Cache-Control: no-cache, private
[...]
Content-Length: 1793
有什么想法吗?
非常感谢。
如 Jeff Sheets 在 this answer 中所述,您的请求配置对象可能包含 responseType: 'json'
。这可能会导致对象被浏览器的底层 XMLHttpRequest 实现删除,该实现在将对象传递回应用程序之前指定了此 属性。
删除 responseType
属性 或将其设置为文本应该可以解决问题。
responseType
记录在 MDN 上,其中指出
Setting the value of responseType to "document" is ignored if done in a Worker environment. When setting responseType to a particular value, the author should make sure that the server is actually sending a response compatible to that format. If the server returns data that is not compatible to the responseType that was set, the value of response will be null. Also, setting responseType for synchronous requests will throw an InvalidAccessError exception.
(强调我的)
我有一个 angular 应用程序与 Api 进行通信,其中我在 JSON 响应前面加上 angular's official documentation 推荐的 )]}',
数组要做。
问题是,我的浏览器似乎在 angular 之前尝试解码响应。
我已经在调试器中一步步进行了,在 xhr.onload
回调被触发后,响应已经是 null.
我说的代码是这个:
// From angular.js(1.5.9):12122
xhr.onload = function requestLoaded() {
var statusText = xhr.statusText || '';
// responseText is the old-school way of retrieving response (supported by IE9)
// response/responseType properties were introduced in XHR Level2 spec (supported by IE10)
var response = ('response' in xhr) ? xhr.response : xhr.responseText;
// normalize IE9 bug (http://bugs.jquery.com/ticket/1450)
var status = xhr.status === 1223 ? 204 : xhr.status;
// fix status code when it is 0 (0 status is undocumented).
// Occurs when accessing file resources or on Android 4.1 stock browser
// while retrieving files from application cache.
if (status === 0) {
status = response ? 200 : urlResolve(url).protocol === 'file' ? 404 : 0;
}
completeRequest(callback,
status,
response,
xhr.getAllResponseHeaders(),
statusText);
};
}
xhr.response
在 angular 做任何事情之前为空(我认为)。
Angular 尝试使用以下代码去除前缀:
function defaultHttpResponseTransform(data, headers) {
if (isString(data)) {
// Strip json vulnerability protection prefix and trim whitespace
var tempData = data.replace(JSON_PROTECTION_PREFIX, '').trim();
if (tempData) {
var contentType = headers('Content-Type');
if ((contentType && (contentType.indexOf(APPLICATION_JSON) === 0)) || isJsonLike(tempData)) {
data = fromJson(tempData);
}
}
}
return data;
}
但此时数据绝不是字符串,浏览器已经尝试对其进行解码(但失败了)。
Api 的输出如下所示:
)]}',
[{"name": "A"},{"name": "B"}]
如果我删除前缀,它可以正常工作。我试过: - 歌剧 45.0 - 火狐 46 - Chrome 58
它们的行为都相似,所以我可能遗漏了一些东西。
响应 headers 包含以下内容:
HTTP/1.1 200 OK
Server: nginx/1.11.5
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Cache-Control: no-cache, private
[...]
Content-Length: 1793
有什么想法吗?
非常感谢。
如 Jeff Sheets 在 this answer 中所述,您的请求配置对象可能包含 responseType: 'json'
。这可能会导致对象被浏览器的底层 XMLHttpRequest 实现删除,该实现在将对象传递回应用程序之前指定了此 属性。
删除 responseType
属性 或将其设置为文本应该可以解决问题。
responseType
记录在 MDN 上,其中指出
Setting the value of responseType to "document" is ignored if done in a Worker environment. When setting responseType to a particular value, the author should make sure that the server is actually sending a response compatible to that format. If the server returns data that is not compatible to the responseType that was set, the value of response will be null. Also, setting responseType for synchronous requests will throw an InvalidAccessError exception.
(强调我的)