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

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&&&.

무슨 일이야?



답변

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를 맹목적으로 실행하므로 무한 루프 또는 구문 오류가 발생합니다.

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


답변

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을 전송하지 않도록 서버 측 변경이 필요합니다.


답변

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

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


답변

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


답변

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


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

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


답변

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


답변

인증이 완료되면 JSON 하이재킹 보호는 다양한 형태를 취할 수 있습니다. Google은 while (1) 을 JSON 데이터에 추가 하여 악의적 인 스크립트가 평가하는 경우 악의적 인 스크립트가 무한 루프에 들어갑니다.

참고: 웹 보안 테스팅 요리 책 : 문제를 빨리 찾아내는 체계적인 기술