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

편집 — 주석 (및 기타 답변)을 기록합니다. 문제는 전복 된 내장 기능, 특히 ObjectArray생성자 와 관련이 있습니다. 그렇지 않으면 무해한 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.