질문자 :Jess
왜 Google은 while(1);
그들의 (비공개) JSON 응답에?
예를 들어 다음은 Google 캘린더 에서 캘린더를 켜고 끄는 동안의 응답입니다.
while (1); [ ['u', [ ['smsSentFlag', 'false'], ['hideInvitations', 'false'], ['remindOnRespondedEventsOnly', 'true'], ['hideInvitations_remindOnRespondedEventsOnly', 'false_true'], ['Calendar ID stripped for privacy', 'false'], ['smsVerifiedFlag', 'true'] ]] ]
eval()
을 수행하는 것을 방지하기 위한 것이라고 가정하지만, 실제로 해야 할 일은 while
교체한 다음 설정하는 것입니다. 평가 방지는 사람들이 안전한 JSON 구문 분석 코드를 작성하도록 하는 것이라고 가정합니다.
다른 곳에서도 이것을 사용하는 것을 보았지만 Google(메일, 캘린더, 연락처 등)에서는 훨씬 더 많이 사용되었습니다. 이상하게도 Google 문서도구 는 &&&START&&&
로 시작하고 Google 주소록은 while(1); &&&START&&&
.
무슨 일이야?
2011년 이후 ECMAScript 5로 모든 주요 브라우저에서 공식적으로 수정된 주요 JSON 보안 문제인 JSON 하이재킹을 방지합니다.
인위적인 예: 받은 편지함의 처음 50개 메시지를 JSON 형식으로 반환하는 mail.google.com/json?action=inbox
와 같은 URL이 Google에 있다고 가정해 보겠습니다. 다른 도메인의 악의적인 웹사이트는 동일 출처 정책으로 인해 이 데이터를 얻기 위해 AJAX 요청을 할 수 없지만 <script>
태그를 통해 URL을 포함할 수 있습니다. URL은 쿠키와 함께 방문하고,하는 것입니다 세계 배열 생성자 또는 접근 방법 오버라이드 (override) 그들을 JSON의 내용을 읽을 수 있도록, 그들이하는 방법은 객체 (배열이나 해쉬) 속성이 설정 될 때마다 불렀다 수 있습니다.
while(1);
또는 &&&BLAH&&&
는 이를 방지합니다. mail.google.com
의 AJAX 요청은 텍스트 콘텐츠에 대한 전체 액세스 권한을 가지며 이를 제거할 수 있습니다. 그러나 <script>
태그 삽입은 아무런 처리 없이 자바스크립트를 맹목적으로 실행하여 무한 루프나 구문 오류가 발생합니다.
이것은 사이트 간 요청 위조 문제를 해결하지 않습니다.
rjhJSON 하이재킹을 통한 응답 공개를 방지합니다.
이론적으로 HTTP 응답의 내용은 동일한 출처 정책에 의해 보호됩니다. 한 도메인의 페이지는 다른 도메인의 페이지에서 정보를 가져올 수 없습니다(명시적으로 허용되지 않는 한).
<script src=...>
또는 <img>
태그를 사용하여 사용자를 대신하여 다른 도메인의 페이지를 요청할 수 있지만 결과(헤더, 내용)에 대한 정보는 얻을 수 없습니다.
따라서 공격자의 페이지를 방문하면 gmail.com에서 보낸 이메일을 읽을 수 없습니다.
스크립트 태그를 사용하여 JSON 콘텐츠를 요청할 때를 제외하고 JSON은 공격자가 제어하는 환경에서 JavaScript로 실행됩니다. 공격자가 Array 또는 Object 생성자 또는 개체 생성 중에 사용되는 다른 방법을 대체할 수 있는 경우 JSON의 모든 항목이 공격자의 코드를 통과하여 공개됩니다.
이것은 JSON이 구문 분석되는 시간이 아니라 JavaScript로 실행될 때 발생합니다.
여러 대책이 있습니다.
JSON이 실행되지 않도록 하기
while(1);
을 배치함으로써; JSON 데이터 앞에 문을 추가하면 Google은 JSON 데이터가 JavaScript로 실행되지 않도록 합니다.
합법적인 페이지만 실제로 전체 콘텐츠를 가져올 수 있습니다. while(1);
, 나머지를 JSON으로 구문 분석합니다.
for(;;);
예를 들어 Facebook에서 동일한 결과가 나타났습니다.
JSON이 유효한 JavaScript가 아닌지 확인
&&&START&&&
와 같이 JSON 앞에 잘못된 토큰을 추가하면 절대 실행되지 않습니다.
항상 외부에 객체가 있는 JSON을 반환합니다.
이것은 JSON 하이재킹으로부터 보호하기 위해 OWASP에서 권장하는 방법이며 덜 방해가 되는 방법입니다.
이전 대응책과 마찬가지로 JSON이 JavaScript로 실행되지 않도록 합니다.
유효한 JSON 객체는 아무 것도 묶이지 않은 경우 JavaScript에서 유효하지 않습니다.
eval('{"foo":"bar"}') // SyntaxError: Unexpected token :
그러나 이것은 유효한 JSON입니다.
JSON.parse('{"foo":"bar"}') // Object {foo: "bar"}
따라서 응답의 최상위 수준에서 항상 Object를 반환하도록 하면 JSON이 유효한 JavaScript인 동시에 유효한 JSON인지 확인할 수 있습니다.
주석에서 @hvd가 언급한 것처럼 빈 객체 {}
는 유효한 JavaScript이며 객체가 비어 있다는 사실 자체가 귀중한 정보일 수 있습니다.
위 방법의 비교
OWASP 방식은 클라이언트 라이브러리를 변경할 필요가 없고 유효한 JSON을 전송하므로 덜 방해가 됩니다. 그러나 과거 또는 미래의 브라우저 버그가 이 문제를 해결할 수 있는지 여부는 확실하지 않습니다. @oriadam이 언급했듯이 오류 처리를 통해 구문 분석 오류에서 데이터가 누출될 수 있는지 여부(예: window.onerror)가 명확하지 않습니다.
Google의 방식은 자동 역직렬화를 지원하기 위해 클라이언트 라이브러리가 필요하며 브라우저 버그와 관련하여 더 안전한 것으로 간주될 수 있습니다.
개발자가 실수로 취약한 JSON을 보내는 것을 방지하기 위해 두 방법 모두 서버 측 변경이 필요합니다.
Arnaud Le Blanc이것은 다른 사이트가 귀하의 데이터를 훔치려는 불쾌한 속임수를 사용하지 못하도록 하기 위한 것입니다. 예를 들어 배열 생성자 <script>
태그를 통해 이 JSON URL을 포함하면 악의적인 타사 사이트가 JSON 응답에서 데이터를 훔칠 수 있습니다. while(1);
시작 시 스크립트가 대신 중단됩니다.
반면에 XHR과 별도의 JSON 파서를 사용하는 동일 사이트 요청은 while(1);
접두사.
bdonlan<script>
태그가 있는 HTML 문서에 JSON 응답을 삽입하기 어렵게 만듭니다. <script>
태그는 동일한 출처 정책 에서 제외됩니다.
Daniel Vassallo참고 : 2019년 현재 이 질문에서 논의된 예방 조치로 이어지는 많은 오래된 취약점은 더 이상 최신 브라우저에서 문제가 되지 않습니다. 아래의 답은 역사적 호기심으로 남겨두겠지만, 실제로 이 질문을 받은 2010년(!!) 이후로 전체 주제가 근본적으로 바뀌었습니다.
<script>
태그의 대상으로 사용되는 것을 방지합니다. (글쎄, 그것은 그것을 막지 못하지만 불쾌하게 만듭니다.) 그렇게 하면 나쁜 사람들이 해당 스크립트 태그를 자신의 사이트에 넣고 활성 세션에 의존하여 콘텐츠를 가져올 수 없습니다.
편집 — 주석(및 기타 답변)을 확인합니다. 이 문제는 전복된 내장 기능, 특히 Object
및 Array
생성자와 관련이 있습니다. 그렇지 않으면 무해한 JSON이 구문 분석될 때 공격자 코드를 트리거할 수 있도록 변경될 수 있습니다.
Pointy<script>
태그는 웹 세계의 보안 필수 사항인 Same Origin Policy에서 제외되기 때문에 JSON 응답에 추가할 때 while(1)
<script>
태그에서 태그의 오용을 방지합니다.
Krishna Ganeriwal이것은 트래픽이 많은 게시물이므로 원래 질문에 대해 약간 더 불확실한 답변을 제공하여 JSON Hijacking 공격 및 그 결과에 대한 추가 배경 정보를 제공하고자 합니다.
이름에서 알 수 있듯이 JSON 하이재킹은 GET 요청에 대한 배열 리터럴로 민감한 데이터를 반환하는 애플리케이션에서 공격자가 도메인 간 중요한 JSON 데이터에 액세스할 수 있는 Cross-Site Request Forgery와 유사한 공격입니다. 배열 리터럴을 반환하는 JSON 호출의 예는 다음과 같습니다.
[{"id":"1001","ccnum":"4111111111111111","balance":"2345.15"}, {"id":"1002","ccnum":"5555555555554444","balance":"10345.00"}, {"id":"1003","ccnum":"5105105105105100","balance":"6250.50"}]
이 공격은 3가지 주요 단계로 달성할 수 있습니다.
1단계: 인증된 사용자가 악성 페이지를 방문하도록 합니다. 2단계: 악성 페이지는 사용자가 로그인한 애플리케이션의 민감한 데이터에 액세스하려고 시도합니다. 이는 스크립트 태그에 동일 출처 정책이 적용되지 않기 때문에 HTML 페이지에 스크립트 태그를 포함하여 수행할 수 있습니다.
<script src="http://<jsonsite>/json_server.php"></script>
json_server.php
GET 요청을 하고 사용자의 인증 쿠키는 요청과 함께 전송됩니다. 3단계: 이 시점에서 악성 사이트는 스크립트를 실행하는 동안 민감한 데이터에 액세스할 수 없습니다. 객체 프로토타입 설정자를 사용하여 데이터에 액세스할 수 있습니다. ccnum
" 속성을 설정하려고 할 때 정의된 함수에 바인딩됩니다.
Object.prototype.__defineSetter__('ccnum',function(obj){ secrets =secrets.concat(" ", obj); });
이 시점에서 악성 사이트는 byjson_server.php
JSON에서 반환된 (ccnum)
모든 브라우저가 이 방법을 지원하는 것은 아닙니다. 개념 증명은 Firefox 3.x에서 수행되었습니다. 이 방법은 이제 더 이상 사용되지 않으며 useObject.defineProperty
로 대체되었습니다. 이 공격의 변형은 전체 이름의 JavaScript(예: pi=3.14159
)가 있는 모든 브라우저에서 작동해야 합니다. JSON 배열 대신 반환됩니다.
JSON 하이재킹을 방지할 수 있는 몇 가지 방법이 있습니다.
SCRIPT 태그는 HTTP GET 요청만 생성할 수 있으므로 JSON 개체만 POST 요청으로 반환합니다.
웹 브라우저가 JSON 개체를 유효한 JavaScript 코드로 해석하지 못하도록 합니다.
모든 JSON 요청에 사전 정의된 임의 값이 필요하도록 요구하여 사이트 간 요청 위조 방지를 구현합니다.
보시 While(1)
은 마지막 옵션 아래에 있습니다. 가장 간단한 용어로, while(1)
은 break 문이 명시적으로 발행될 때까지 실행되는 무한 루프입니다. 따라서 적용할 키에 대한 잠금으로 설명되는 것(google break 문)입니다. 따라서 Hacker에 키가 없는 JSON 하이재킹은 일관되게 해제됩니다. 아아, 파서로 JSON 블록을 읽으면 while(1) 루프가 무시됩니다.
따라서 결론적으로 while(1)
루프는 Google이 데이터 흐름을 제어하는 데 사용할 수 있는 간단한 break 문 암호로 더 쉽게 시각화할 수 있습니다.
그러나 그 문장의 키워드는 ' 단순 '입니다. 인증된 무한 루프의 사용은 격리 되었을 때 CPU 사용량의 절대적인 감소로 인해 2010 년 이후 기본 관행에서 감사하게도 제거되었습니다. 대신 오늘날 코드베이스에는 예방 조치가 포함되어 있으며 시스템은 더 이상 중요하지도 효과적이지도 않습니다. (이 중 일부는 JSON Hijacking에서 현재 다루지 않을 보다 유익한 데이터 파밍 기술로 이동하는 것입니다)
MontresorXPL인증이 이루어진 후 JSON 하이재킹 보호는 다양한 형태를 취할 수 있습니다. Google 은 JSON 데이터에 while(1) 을 추가하여 악성 스크립트가 이를 평가하면 악성 스크립트가 무한 루프에 진입합니다.
참조: 웹 보안 테스트 쿡북: 문제를 빠르게 찾기 위한 체계적인 기술
JSON C11출처 : 여기를 클릭하세요
출처 : http:www.stackoverflow.com/questions/2669690/why-does-google-prepend-while1-to-their-json-responses