아니요, 더 이상 Firefox 21, Chrome 27 또는 IE 10에서 []
또는 {}
생성자에 전달 된 값을 캡처 할 수 없습니다 . http://www.thespanner.co.uk에 설명 된 주요 공격을 기반으로 한 약간의 테스트 페이지가 있습니다 . / 2011 / 05 / 30 / json-hijacking / :
( http://jsfiddle.net/ph3Uv/2/ )
var capture = function() {
var ta = document.querySelector('textarea')
ta.innerHTML = '';
ta.appendChild(document.createTextNode("Captured: "+JSON.stringify(arguments)));
return arguments;
}
var original = Array;
var toggle = document.body.querySelector('input[type="checkbox"]');
var toggleCapture = function() {
var isOn = toggle.checked;
window.Array = isOn ? capture : original;
if (isOn) {
Object.defineProperty(Object.prototype, 'foo', {set: capture});
} else {
delete Object.prototype.foo;
}
};
toggle.addEventListener('click', toggleCapture);
toggleCapture();
[].forEach.call(document.body.querySelectorAll('input[type="button"]'), function(el) {
el.addEventListener('click', function() {
document.querySelector('textarea').innerHTML = 'Safe.';
eval(this.value);
});
});
<div><label><input type="checkbox" checked="checked"> Capture</label></div>
<div><input type="button" value="[1, 2]" /> <input type="button" value="Array(1, 2);" /> <input type="button" value="{foo: 'bar'}" /> <input type="button" value="({}).foo = 'bar';" /></div>
<div><textarea></textarea></div>
짧은 형식과 긴 형식을 통해 배열과 객체를 초기화 window.Array
하고 setter를 재정의 하고 추가 Object.prototype.foo
합니다.
ES4 사양은 , 섹션 1.5에서 구현 전례와 노트 "새로운 객체와 배열 초기화에 대한 객체를 구성하는 데 사용되는 객체와 배열의 글로벌 표준 바인딩을 필요로"인터넷 익스플로러 6, 오페라 9.20 및 Safari 3 할 일 "그 "Object 및 Array의 로컬 또는 전역 리 바인딩을 존중하지 않고 원래 Object 및 Array 생성자를 사용하십시오." 이것은 ES5 섹션 11.1.4 에서 유지됩니다 .
Allen Wirfs-Brock 은 ES5는 DefineOwnProperty를 사용하기 때문에 객체 초기화가 setter를 트리거하지 않아야한다고 명시하고 있다고 설명 했다. MDN : Objects를 사용한 작업 은 "JavaScript 1.8.1부터는 객체 및 배열 이니셜 라이저에서 속성을 설정할 때 세터가 더 이상 호출되지 않습니다"라고 말합니다. 이것은 V8 문제 1015 에서 해결되었습니다 .