최신 브라우저에서 JSON 하이재킹이 여전히 문제가됩니까?


149

Backbone.js와 Tornado 웹 서버를 사용하고 있습니다. Backbone에서 컬렉션 데이터를 수신하는 표준 동작은 JSON 배열로 전송하는 것입니다.

반면 토네이도의 표준 동작은 다음과 같은 취약점으로 인해 JSON 어레이를 허용하지 않는 것입니다.

http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx

관련있는 것은 : http://haacked.com/archive/2009/06/25/json-hijacking.aspx

JSON이 실제로 객체 목록 일 때 객체를 묶을 필요가없는 것이 더 자연스러운 느낌입니다.

최신 브라우저 (예 : 현재 Chrome, Firefox, Safari 및 IE9)에서는 이러한 공격을 재현 할 수 없었습니다. 동시에 현대 브라우저가 이러한 문제를 해결했다는 것을 어디에서나 확인할 수 없었습니다.

가능한 프로그래밍 기술이나 인터넷 검색 기술에 의해 오도되지 않도록하려면 :

오늘날 JSON 브라우저에서 이러한 JSON 하이재킹 공격이 여전히 문제가됩니까?

(참고 : 중복 가능성으로 죄송합니다 : 최신 브라우저에서 'JSON 하이재킹'을 수행 할 수 있습니까? 하지만 허용 된 답변이 질문에 대답하지 않는 것 같습니다. 다시 질문하고 더 명확한 설명을 얻을 시간이라고 생각했습니다. .)


평가 사용? 백본 파싱 응답에서 변경되거나 변경된 것이 없다면 안전해야합니다
Deeptechtons

10
일반적으로 누군가가 "현대"브라우저를 사용한다는 가정하에 웹 보안에 접근해서는 안됩니다.
Luke

7
@Luke-Reid에 대한 아래 설명을 참조하십시오. 일반적으로 좋은 지적이지만 일반적인 보안 질문은 아닙니다. (내 사용자는 처음에 최신 브라우저를 사용하는 경우에만 인증 할 수 있습니다.)
Rocketman

4
@Luke, 때때로 우리는 지금 나아가서 적용되는 것처럼 보이는 경우 이전 위협으로부터 보호하지 않고 현대적인 패턴 (이 경우 REST와 같은 데이터를 얻는 것은 GET 작업이며 다른 것이어서는 안 됨)으로 발전시켜야합니다. 작은 청중에게. 따라서이 질문은 자신의 응용 사례에 대해이 위협을 무시할 수 있는지 여부를 평가할 수 있도록하는 데 매우 유용합니다. 언젠가는 더 이상 사용되지 않는 소프트웨어를 사용하는 사용자는 다른 종류의 위협 (악성 프로그램)을 가지고있을 가능성이 높습니다.
Frédéric

2
@jpaugh, 그런 가정은 어디에서 보입니까? 나는 쓸모없는 소프트웨어를 가진 사람들이 어쨌든 "보호 할 수 없다"고 생각합니다. (내 스케이트 비용을 정당화하는 것에 대해, 나는 이미 현재 스케이트를 착용하는 데 걸리는 시간의 3 분의 1 이하로 마모 된 카본 스피드 스케이트에 그들의 가격의 3 분의 1을 넣는 데 익숙했습니다. 당신이 그들을 타기를 좋아한다면 그것이 가치가 있다고 생각합니다. 제 경우입니다.)
Frédéric

답변:


112

아니요, 더 이상 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 에서 해결되었습니다 .


28
2009 년 Brendan Eich는 브라우저가 스크립트를 application / json ( bugzilla.mozilla.org/show_bug.cgi?id=376957#c75 ) 으로 제공하는 스크립트를 평가하지 말라고 제안했지만 여전히 좋은 생각입니다.

2
블라인드 POST CSRF는 특히 텍스트 / 일반 인코딩과 같은 양식을 사용하여 여전히 가능하며 토큰 / nonces를 사용하여 제거해야합니다.

1
POST CSRF에 예. 훌륭한 정보를 제공해 주셔서 감사합니다.
Rocketman 2016 년

5
Array 생성자를 덮어 쓰는 것만 언급하면 ​​올바른 문장입니다. Microsoft의 IE와 Edge는 여전히 UTF-7 JSON 하이재킹에 취약합니다. 최근에 테스트했으며 (오늘 다시 재미를 위해) 여전히 작동합니다.
user857990

2
Gareth Heyes 덕분에 UTF-16BE도 마찬가지입니다. blog.portswigger.net/2016/11/json-hijacking-for-modern-web.html
eel ghEEz
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.