Google이 왜 prepend (1); 그들의 JSON 응답에?


4074

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 (Mail, 캘린더, 연락처 등)에서도 훨씬 더 그렇습니다. 이상하게도 Google 문서 는 &&&START&&&대신 시작 하고 Google 연락처는로 시작하는 것 같습니다 while(1); &&&START&&&.

무슨 일이야?


45
첫 인상이 맞다고 생각합니다. 코드를 찾기 시작하고 소스에 따라 입력 스트림을 트리밍하려고 시도하면 재고를 확보하고 안전한 방식으로 (Google의 작업으로 인해 더 쉬워 짐) 수행해야합니다.
— Esteban Küber

34
아마도 후속 질문 : 왜 구글이 )]}'대신에 지금 선행 while(1);합니까? 답이 같을까요?
— 기즈모

3
무한 루프가 아닌 평가를 방지합니다.
— Mardoxx

9
이것은 1 바이트를 저장하는 )]}'페이스 북처럼 바이트를 저장하는 것일 수도 있습니다 for(;;);:)
— Gras Double

3
json의 공개를 방지하기 위해JSON hijacking
— Ashraf.Shk786

답변:


4293

2011 년 이후 모든 주요 브라우저에서 공식적으로 수정 된 주요 JSON 보안 문제인 JSON 하이재킹을 방지 합니다. 인 ECMAScript 5를.

고안된 예 : Google에 mail.google.com/json?action=inbox받은 편지함의 처음 50 개 메시지를 JSON 형식으로 반환 하는 URL이 있다고 가정 합니다. 다른 도메인의 악의적 인 웹 사이트는 동일한 출처 정책으로 인해 AJAX에이 데이터를 요청하지 않지만 <script>태그 를 통해 URL을 포함 할 수 있습니다 . URL이 함께 방문 하여 쿠키, 그리고에 의해 세계 배열 생성자 또는 접근 방법 오버라이드 (override) 그들을 JSON의 내용을 읽을 수 있도록, 그들이하는 방법은 객체 (배열이나 해쉬) 속성이 설정 될 때마다 불렀다 수 있습니다.

while(1);또는 &&&BLAH&&&방지이 :에서 AJAX 요청이 mail.google.com텍스트 내용에 대한 전체 액세스 권한을 갖게됩니다, 그리고 그것을 멀리 제거 할 수 있습니다. 그러나 <script>태그 삽입은 처리없이 JavaScript를 맹목적으로 실행하므로 무한 루프 또는 구문 오류가 발생합니다.

교차 사이트 요청 위조 문제는 다루지 않습니다 .


228
이 데이터를 얻는 요청에 CSRF 토큰이 필요한 이유는 무엇입니까?
— Jakub P.

235
않습니다 for(;;);같은 일을 할? 나는 페이스 북의 아약스 응답에서 이것을 보았다.
— 줄리앙 왕

183
@JakubP. Google 규모로 CSRF 토큰을 저장하고 유지하려면 많은 인프라와 비용이 필요합니다.
— abraham

127
@JakubP. anti-CSRF 토큰은 캐싱을 망쳐 놓고 서버 측에서 어느 정도의 암호화 평가가 필요합니다. 구글 규모에서는 많은 CPU가 필요합니다. 이런 종류의 클라이언트로 클라이언트를 오프로드합니다.
— bluesmoon

96
올바른 헤더가 설정된 경우 서버가 JSON 만 보내도록하는 것이 더 좋은 방법입니다. 스크립트 태그로는 AJAX 호출로 할 수 있습니다. 이렇게하면 중요한 정보가 전송되지 않으며 브라우저 측 보안에 의존 할 필요가 없습니다.
— mcv

574

JSON 하이재킹을 통한 응답 공개를 방지합니다.

이론적으로 HTTP 응답의 내용은 동일한 출처 정책으로 보호됩니다. 명시 적으로 허용되지 않는 한 한 도메인의 페이지는 다른 도메인의 페이지에서 정보를 얻을 수 없습니다.

공격자는 사용자를 대신하여 다른 도메인의 페이지를 요청할 수 있습니다 (예 : <script src=...>또는<img> 태그 있지만 결과에 대한 정보 (헤더, 내용)는 얻을 수 없습니다.

따라서 침입자 페이지를 방문하면 gmail.com에서 전자 메일을 읽을 수 없습니다.

스크립트 태그를 사용하여 JSON 컨텐츠를 요청하는 경우를 제외하고 JSON은 공격자의 제어 환경에서 Javascript로 실행됩니다. 공격자가 Array 또는 Object 생성자 또는 객체 생성 중에 사용 된 다른 방법을 교체 할 수 있으면 JSON의 모든 항목이 침입자의 코드를 통과하여 공개됩니다.

이는 JSON이 구문 분석 될 때가 아니라 Javascript로 실행될 때 발생합니다.

여러 가지 대책이 있습니다.

JSON이 절대로 실행되지 않도록 확인

배치함으로써 while(1);Google은 JSON 데이터 앞에 명령문 하여 JSON 데이터가 Javascript로 실행되지 않도록합니다.

합법적 인 페이지 만 전체 콘텐츠를 얻을 수 있습니다. while(1); 오고를 하고 나머지를 JSON으로 구문 분석 할 수 있습니다.

같은 것들 for(;;); 동일한 결과로, 예를 들어 페이스 북에서 볼 수있다.

JSON이 유효한 Javascript가 아닌지 확인

마찬가지로 JSON 앞에 유효하지 않은 토큰 추가 &&&START&&& 하면 실행되지 않습니다.

항상 외부에 객체가있는 JSON을 반환하십시오.

이것은 OWASP권장되는 방법입니다 JSON 하이재킹을 방지 데 이며 덜 방해가되는 입니다.

이전 대책과 마찬가지로 JSON이 Javascript로 실행되지 않도록합니다.

아무것도 포함하지 않을 경우 유효한 JSON 객체는 Javascript에서 유효하지 않습니다.

eval('{"foo":"bar"}')
// SyntaxError: Unexpected token :

그러나 이것은 유효한 JSON입니다.

JSON.parse('{"foo":"bar"}')
// Object {foo: "bar"}

따라서 응답의 최상위 수준에서 항상 Object를 반환해야 JSON이 유효한 JSON이면서 JSON이 유효한 Javascript가 아닌지 확인할 수 있습니다.

주석에서 @ hvd가 언급했듯이 빈 객체 {}는 유효한 Javascript이며 객체가 비어 있다는 것은 그 자체가 가치있는 정보 일 수 있습니다.

위의 방법 비교

클라이언트 라이브러리를 변경할 필요가없고 유효한 JSON을 전송하므로 OWASP 방식은 덜 방해가되지 않습니다. 그러나 과거 또는 미래의 브라우저 버그로이 문제를 해결할 수 있는지 확실하지 않습니다. @oriadam이 지적했듯이, 오류 처리를 통해 구문 분석 오류로 데이터가 유출 될 수 있는지 여부는 확실하지 않습니다 (예 : window.onerror).

구글의 방법은 자동 역 직렬화를 지원하기 위해 클라이언트 라이브러리가 필요하며 브라우저 버그에 대해 더 안전한 것으로 간주 될 수 있습니다.

두 방법 모두 개발자가 실수로 취약한 JSON을 전송하지 않도록 서버 측 변경이 필요합니다.


23
OWASP 추천은 단순하기 때문에 흥미 롭습니다. Google의 방식이 더 안전한 이유를 아는 사람이 있습니까?
— funroll

18
나는 그것이 더 안전 하지 않다고 생각합니다 . 여기에 OWASP를 제공하면 +1의 충분한 이유가됩니다.

30
왜 객체 리터럴을 반환하면 script태그 나 eval함수 가 실패 하는지 주목할 가치가 있습니다. 중괄호 {}는 코드 블록 또는 객체 리터럴로 해석 될 수 있으며, JavaScript는 그 자체로 전자를 선호합니다. 물론 코드 블록으로는 유효하지 않습니다. 이 논리에 따르면 향후 브라우저 동작에서 예측 가능한 변경 사항을 볼 수 없습니다.
— Manngo

16
공격자가 브라우저의 스크립트 오류 처리자를 납치 할 수 있기 때문에 잘못된 코드로는 충분하지 않습니다 ( window.onerror) onerror. 구문 오류 의 동작이 무엇인지 잘 모르겠습니다 . 구글도 확실하지 않은 것 같습니다.
— oriadam

12
"무엇으로도 포함되지 않은 유효한 JSON 객체는 Javascript에서 유효하지 않습니다."-빈 객체 ( {}) 의 사소한 경우를 제외하고 는 유효한 빈 블록입니다. 객체가 비어 있다는 사실 자체가 귀중한 정보 일 수 있다면, 이는 악용 될 수 있습니다.

371

이것은 다른 사이트가 데이터를 훔치려 고 시도하는 속임수를 쓰지 않도록하기위한 것입니다. 예를 들어, 배열 생성자 를 교체 한 다음 <script>태그 를 통해이 JSON URL을 포함 시키면 악의적 인 타사 사이트가 JSON 응답에서 데이터를 훔칠 수 있습니다. while(1);시작 부분에 를 넣으면 대신 스크립트가 중단됩니다.

반면에 XHR과 별도의 JSON 파서를 사용하는 동일한 사이트 요청은 while(1);접두사를 쉽게 무시할 수 있습니다 .


6
기술적으로 접두어가 있으면 "일반"JSON 파서에서 오류가 발생합니다.
— Matthew Crumley

12
공격자는 <script>XHR이 아닌 일반 오래된 요소를 사용합니다 .
— Laurence Gonsalves 4

9
@Matthew는 물론 JSON 파서에 데이터를 전달하기 전에 제거 할 수 있습니다. 당신은 <script>태그 와 함께 그것을 할 수 없습니다
— bdonlan

7
이에 대한 예가 있습니까? 배열 생성자를 교체하는 것은 다시 참조되지만 버그가 수정되었습니다. 스크립트 태그를 통해 수신 된 데이터에 어떻게 액세스 할 수 있는지 이해할 수 없습니다. 최근 브라우저에서 작동하는 더미 구현을보고 싶습니다.
— Dennis G

7
@joeltine, 아니, 그렇지 않습니다. stackoverflow.com/questions/16289894/…를 참조하십시오 .

111

이는 타사가 <script>태그 를 사용하여 JSON 응답을 HTML 문서에 삽입하는 것을 어렵게 만듭니다 . 기억 <script>태그가 면제 동일 기원 정책 .


21
이것은 절반의 답입니다. Objectand Array생성자 를 재정의하는 트릭이 아니었다면 JavaScript 인 것처럼 유효한 JSON 응답을 실행하는 것이 모든 상황에서 완전히 무해한 것입니다. 그렇습니다 while(1);. <script>태그로 대상이 지정된 경우 응답이 JavaScript로 실행되는 것을 방지 하지만 필요한 이유를 설명하지 않습니다.
— Mark Amery

하지만 iframe을 방지하는 방법
— Ravinder하기 Payal

스크립트 태그는 동일한 원본 정책에서 면제되지 않습니다. 나를 위해 그것을 정리할 수 있습니까?
— Suraj Jain

82

참고 : 2019 년 현재이 질문에서 논의 된 예방 조치로 이어지는 많은 오래된 취약점은 더 이상 최신 브라우저에서 문제가되지 않습니다. 아래의 답을 역사적 호기심으로 남겨 두겠습니다. 그러나 이것이 요청되었을 때 실제로 모든 주제는 2010 년 이후 급격히 변했습니다 (!!).


단순 <script>태그 의 대상으로 사용되지 않습니다 . (잘 막지는 않지만, 불쾌하게 만듭니다.) 그렇게 나쁜 사람들은 스크립트 태그를 자신의 사이트에 넣을 수없고 액티브 세션에 의존하여 콘텐츠를 가져올 수 없습니다.

편집 — 주석 (및 기타 답변)을 기록합니다. 문제는 전복 된 내장 기능, 특히 Object및 Array생성자 와 관련이 있습니다. 그렇지 않으면 무해한 JSON이 구문 분석 될 때 공격자 코드를 트리거 할 수 있도록 변경 될 수 있습니다.


17
이것은 절반의 답입니다. Objectand Array생성자 를 재정의하는 트릭이 아니었다면 JavaScript 인 것처럼 유효한 JSON 응답을 실행하는 것이 모든 상황에서 완전히 무해한 것입니다. 그렇습니다 while(1);. <script>태그로 대상이 지정된 경우 응답이 JavaScript로 실행되는 것을 방지 하지만 필요한 이유를 설명하지 않습니다.
— Mark Amery

11

때문에 <script>태그가 웹 세계에서 보안의 필요성 동일한 기원 정책 면제, while(1)JSON 응답의 방지에 추가 할 때에 잘못 <script>태그입니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.