Tại sao Google trả trước trong khi (1); phản hồi JSON của họ?


4077

Tại sao Google trả trước while(1);các phản hồi JSON (riêng tư) của họ?

Ví dụ: đây là phản hồi trong khi bật và tắt lịch trong Lịch Google :

while (1);
[
  ['u', [
    ['smsSentFlag', 'false'],
    ['hideInvitations', 'false'],
    ['remindOnRespondedEventsOnly', 'true'],
    ['hideInvitations_remindOnRespondedEventsOnly', 'false_true'],
    ['Calendar ID stripped for privacy', 'false'],
    ['smsVerifiedFlag', 'true']
  ]]
]

Tôi cho rằng điều này là để ngăn mọi người thực hiện eval()nó, nhưng tất cả những gì bạn thực sự phải làm là thay thế whilevà sau đó bạn sẽ được thiết lập. Tôi cho rằng phòng ngừa tệ nạn là đảm bảo mọi người viết mã phân tích cú pháp JSON an toàn.

Tôi cũng đã thấy điều này được sử dụng ở một vài nơi khác, nhưng với Google (Thư, Lịch, Danh bạ, v.v.) Thật kỳ lạ, thay vào đó, Google Docs bắt đầu bằng &&&START&&&và Liên hệ Google dường như bắt đầu bằng while(1); &&&START&&&.

Những gì đang xảy ra ở đây?


45
Tôi tin rằng ấn tượng đầu tiên của bạn là chính xác. Nếu bạn bắt đầu tìm kiếm mã và cố gắng cắt luồng đầu vào tùy thuộc vào nguồn, bạn sẽ xem xét lại và thực hiện theo cách an toàn (và vì hành động của Google, dễ dàng hơn).
Esteban Küber

34
có lẽ là một câu hỏi tiếp theo: Tại sao google trả trước )]}'ngay bây giờ thay vì while(1);? Các câu trả lời sẽ giống nhau?
Gizmo

3
Sẽ ngăn chặn eval, nhưng không phải với một vòng lặp vô hạn.
Mardoxx

9
Điều này )]}'cũng có thể là để lưu byte, như facebook đã sử dụng for(;;);để tiết kiệm một byte :)
Gras Double

3
Đặt hàng để ngăn chặn tiết lộ của json tức làJSON hijacking
Ashraf.Shk786

Câu trả lời:


4293

Nó ngăn chặn việc chiếm quyền điều khiển JSON , một vấn đề bảo mật JSON chính được khắc phục chính thức trong tất cả các trình duyệt chính kể từ năm 2011 với ECMAScript 5.

Ví dụ có thể xảy ra: giả sử Google có một URL giống như mail.google.com/json?action=inboxtrả về 50 tin nhắn đầu tiên trong hộp thư đến của bạn ở định dạng JSON. Các trang web độc ác trên các tên miền khác không thể thực hiện các yêu cầu AJAX để có được dữ liệu này do chính sách cùng nguồn gốc, nhưng chúng có thể bao gồm URL thông qua <script>thẻ. URL được truy cập bằng cookie của bạn và bằng cách ghi đè phương thức trình tạo hoặc trình truy cập mảng toàn cục, họ có thể có một phương thức được gọi bất cứ khi nào thuộc tính đối tượng (mảng hoặc hàm băm) được đặt, cho phép chúng đọc nội dung JSON.

Các while(1);hoặc &&&BLAH&&&ngăn chặn điều này: một yêu cầu AJAX tại mail.google.comsẽ có quyền truy cập đầy đủ đến nội dung văn bản, và có thể tước nó đi. Nhưng <script>việc chèn thẻ thực thi JavaScript một cách mù quáng mà không xử lý, dẫn đến một vòng lặp vô hạn hoặc lỗi cú pháp.

Điều này không giải quyết vấn đề giả mạo yêu cầu chéo trang web .


228
Tại sao yêu cầu lấy dữ liệu này lại yêu cầu mã thông báo CSRF thay thế?
Jakub P.

235
for(;;);làm cùng một công việc? Tôi đã thấy điều này trong các phản hồi ajax của facebook.
Vua Julien

183
@JakubP. Việc lưu trữ và duy trì mã thông báo CSRF ở quy mô của Google đòi hỏi một lượng lớn cơ sở hạ tầng và chi phí.
abraham

127
@JakubP. mã thông báo chống CSRF gây rối với bộ nhớ đệm và yêu cầu một số lượng máy chủ đánh giá mật mã phía máy chủ. Ở quy mô Google, điều đó sẽ đòi hỏi rất nhiều CPU. Đây là loại giảm tải cho khách hàng.
bluesmoon

96
Đối với tôi, có vẻ như một cách tốt hơn là để máy chủ chỉ gửi JSON nếu tiêu đề chính xác đã được đặt. Bạn có thể làm điều đó trong một cuộc gọi AJAX, nhưng không phải với các thẻ script. Bằng cách đó, thông tin nhạy cảm thậm chí không bao giờ được gửi và bạn không phải phụ thuộc vào bảo mật phía trình duyệt.
mcv

574

Nó ngăn tiết lộ phản hồi thông qua việc chiếm quyền điều khiển JSON.

Về lý thuyết, nội dung của các phản hồi HTTP được bảo vệ bởi Chính sách nguồn gốc giống nhau: các trang từ một tên miền không thể nhận được bất kỳ mẩu thông tin nào từ các trang trên tên miền khác (trừ khi được cho phép rõ ràng).

Kẻ tấn công có thể yêu cầu các trang trên các tên miền khác thay mặt bạn, ví dụ: bằng cách sử dụng một <script src=...>hoặc<img> thẻ thẻ, nhưng nó không thể nhận được bất kỳ thông tin nào về kết quả (tiêu đề, nội dung).

Do đó, nếu bạn truy cập trang của kẻ tấn công, nó không thể đọc email của bạn từ gmail.com.

Ngoại trừ khi sử dụng thẻ script để yêu cầu nội dung JSON, JSON được thực thi dưới dạng Javascript trong môi trường do kẻ tấn công kiểm soát. Nếu kẻ tấn công có thể thay thế hàm tạo Array hoặc Object hoặc một số phương thức khác được sử dụng trong quá trình xây dựng đối tượng, mọi thứ trong JSON sẽ chuyển qua mã của kẻ tấn công và được tiết lộ.

Lưu ý rằng điều này xảy ra tại thời điểm JSON được thực thi dưới dạng Javascript, chứ không phải tại thời điểm nó được phân tích cú pháp.

Có nhiều biện pháp đối phó:

Đảm bảo JSON không bao giờ thực thi

Bằng cách đặt một while(1);câu lệnh trước dữ liệu JSON, Google đảm bảo rằng dữ liệu JSON không bao giờ được thực thi dưới dạng Javascript.

Chỉ một trang hợp pháp mới có thể lấy toàn bộ nội dung, loại bỏ while(1);và phân tích phần còn lại dưới dạng JSON.

Những điều như for(;;);đã được nhìn thấy tại Facebook chẳng hạn, với kết quả tương tự.

Đảm bảo JSON không hợp lệ Javascript

Tương tự, việc thêm các mã thông báo không hợp lệ trước JSON, như &&&START&&&, đảm bảo rằng nó không bao giờ được thực thi.

Luôn trả lại JSON với một đối tượng ở bên ngoài

Đây là OWASPcách được khuyến nghị để bảo vệ khỏi việc chiếm quyền điều khiển JSON và là cách ít xâm phạm hơn.

Tương tự như các biện pháp đối phó trước đây, nó đảm bảo rằng JSON không bao giờ được thực thi dưới dạng Javascript.

Một đối tượng JSON hợp lệ, khi không được bao quanh bởi bất kỳ thứ gì, không hợp lệ trong Javascript:

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

Tuy nhiên, đây là JSON hợp lệ:

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

Vì vậy, hãy đảm bảo bạn luôn trả về một Đối tượng ở mức cao nhất của phản hồi, đảm bảo rằng JSON không phải là Javascript hợp lệ, trong khi vẫn là JSON hợp lệ.

Theo ghi nhận của @hvd trong các bình luận, đối tượng trống {}là Javascript hợp lệ và việc biết đối tượng trống có thể là thông tin có giá trị.

So sánh các phương pháp trên

Cách OWASP ít xâm phạm hơn, vì nó không cần thay đổi thư viện khách và chuyển JSON hợp lệ. Tuy nhiên, không chắc là các lỗi trình duyệt trong quá khứ hay tương lai có thể đánh bại điều này hay không. Theo ghi nhận của @oriadam, không rõ liệu dữ liệu có thể bị rò rỉ trong lỗi phân tích cú pháp thông qua xử lý lỗi hay không (ví dụ: window.onerror).

Cách của Google yêu cầu thư viện máy khách hỗ trợ thư viện tự động hóa và có thể được coi là an toàn hơn đối với các lỗi trình duyệt.

Cả hai phương pháp đều yêu cầu thay đổi phía máy chủ để tránh các nhà phát triển vô tình gửi JSON dễ bị tổn thương.


23
Khuyến nghị của OWASP rất thú vị vì tính đơn giản của nó. Bất cứ ai cũng biết một lý do theo cách của Google là an toàn hơn?
funroll 15/03 '

18
Tôi tin rằng nó không an toàn hơn bằng mọi cách. Cung cấp OWASP ở đây có vẻ là một lý do đủ tốt cho +1.

30
Có thể đáng chú ý tại sao việc trả lại một đối tượng theo nghĩa đen không thành công scriptthẻ hoặc evalchức năng. Các dấu ngoặc nhọn {}có thể được hiểu là một khối mã hoặc một đối tượng theo nghĩa đen và chính nó, JavaScript thích cái trước hơn. Như một khối mã, tất nhiên, không hợp lệ. Theo logic này, tôi không thể thấy bất kỳ thay đổi có thể thấy trước trong hành vi trình duyệt trong tương lai.
Manngo

16
Mã xấu là không đủ vì kẻ tấn công cũng có thể chiếm quyền điều khiển trình xử lý lỗi tập lệnh của trình duyệt ( window.onerror) Tôi không chắc hành vi của onerrorlỗi cú pháp là gì. Tôi đoán Google cũng không chắc chắn.
oriadam

12
"Một đối tượng JSON hợp lệ, khi không được bao bọc bởi bất kỳ thứ gì, không hợp lệ trong Javascript:" - Ngoại trừ trường hợp tầm thường của một đối tượng trống ( {}), cũng là một khối trống hợp lệ. Nếu biết đối tượng trống có thể chính nó là thông tin có giá trị, điều này có thể được khai thác.

371

Điều này là để đảm bảo một số trang web khác không thể thực hiện các thủ đoạn khó chịu để cố lấy cắp dữ liệu của bạn. Ví dụ: bằng cách thay thế hàm tạo mảng , sau đó bao gồm URL JSON này thông qua <script>thẻ, trang web bên thứ ba độc hại có thể đánh cắp dữ liệu từ phản hồi JSON. Bằng cách đặt một while(1);ở đầu, kịch bản sẽ treo thay thế.

Mặt khác, một yêu cầu cùng trang web sử dụng XHR và một trình phân tích cú pháp JSON riêng biệt, có thể dễ dàng bỏ qua while(1);tiền tố.


6
Về mặt kỹ thuật, trình phân tích cú pháp JSON "bình thường" sẽ báo lỗi nếu bạn có tiền tố.
Matthew Crumley

12
Những kẻ tấn công sẽ chỉ sử dụng một <script>yếu tố cũ đơn giản , không phải là XHR.
Laurence Gonsalves

9
@Matthew, chắc chắn, nhưng bạn có thể xóa nó trước khi truyền dữ liệu tới trình phân tích cú pháp JSON. Bạn không thể làm điều đó với một <script>thẻ
bdonlan

7
Có bất kỳ ví dụ về điều này? Thay thế hàm tạo mảng được tham chiếu lại, nhưng đó là một lỗi đã được sửa lâu. Tôi không hiểu làm thế nào một người có quyền truy cập vào dữ liệu nhận được thông qua thẻ script. Tôi rất muốn thấy một triển khai giả hoạt động trong trình duyệt gần đây.
Dennis G

7
@joeltine, không, không phải vậy. Xem stackoverflow.com/questions/16289894/ Mạnh .

111

Điều đó sẽ gây khó khăn cho bên thứ ba khi chèn phản hồi JSON vào tài liệu HTML bằng <script>thẻ. Hãy nhớ rằng <script>thẻ được miễn từ Chính sách xuất xứ tương tự .


21
Đây chỉ là một nửa câu trả lời. Nếu đó không phải là thủ thuật ghi đè Objectvà các nhà Arrayxây dựng, thì việc thực hiện phản hồi JSON hợp lệ như thể đó là JavaScript sẽ hoàn toàn vô hại trong mọi trường hợp. Có, while(1);ngăn không cho phản hồi được thực thi dưới dạng JavaScript nếu được nhắm mục tiêu bởi <script>thẻ, nhưng câu trả lời của bạn không giải thích được tại sao điều đó lại cần thiết.
Đánh dấu Amery

nhưng làm thế nào nó sẽ ngăn chặn iframe
Ravinder Payal

Thẻ script không bao giờ được miễn cho cùng một chính sách xuất xứ. Bạn có thể làm rõ điều đó cho tôi?
Suraj Jain

82

Lưu ý : kể từ năm 2019, nhiều lỗ hổng cũ dẫn đến các biện pháp phòng ngừa được thảo luận trong câu hỏi này không còn là vấn đề trong các trình duyệt hiện đại. Tôi sẽ để lại câu trả lời dưới đây như một sự tò mò lịch sử, nhưng thực sự toàn bộ chủ đề đã thay đổi hoàn toàn kể từ năm 2010 (!!) khi điều này được hỏi.


Nó ngăn không cho nó được sử dụng làm mục tiêu của một <script>thẻ đơn giản . (Chà, điều đó không ngăn cản được, nhưng điều đó làm cho nó khó chịu.) Theo cách đó, những kẻ xấu không thể đặt thẻ script đó vào trang web của riêng chúng và dựa vào một phiên hoạt động để có thể tìm nạp nội dung của bạn.

chỉnh sửa - lưu ý nhận xét (và các câu trả lời khác). Vấn đề này đã làm với lật đổ được xây dựng cơ sở vật chất, đặc biệt là ObjectArraynhà xây dựng. Chúng có thể được thay đổi sao cho JSON vô hại, khi được phân tích cú pháp, có thể kích hoạt mã kẻ tấn công.


17
Đây chỉ là một nửa câu trả lời. Nếu đó không phải là thủ thuật ghi đè Objectvà các nhà Arrayxây dựng, thì việc thực hiện phản hồi JSON hợp lệ như thể đó là JavaScript sẽ hoàn toàn vô hại trong mọi trường hợp. Có, while(1);ngăn không cho phản hồi được thực thi dưới dạng JavaScript nếu được nhắm mục tiêu bởi <script>thẻ, nhưng câu trả lời của bạn không giải thích được tại sao điều đó lại cần thiết.
Đánh dấu Amery

11

Do <script>thẻ được miễn trừ khỏi Chính sách xuất xứ tương tự, đây là một điều cần thiết về bảo mật trong thế giới web, nên while(1)khi được thêm vào phản hồi JSON sẽ ngăn chặn việc sử dụng sai mục đích trong <script>thẻ.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.