Tại sao không có chính sách cùng nguồn gốc cho WebSockets? Tại sao tôi có thể kết nối với ws: // localhost?


84

Tôi muốn sử dụng WebSockets để giao tiếp giữa các tiến trình cho ứng dụng của mình (Daemon <-> WebGUI và Daemon <-> FatClient, v.v.). Trong quá trình thử nghiệm, tôi đã thử kết nối với máy chủ ổ cắm web đang chạy cục bộ của mình (ws: // localhost: 1234) thông qua ứng dụng JavaScript WebSocket trên websocket.org ( http://www.websocket.org/echo.html ).

Câu hỏi của tôi bây giờ là:
Tại sao điều này có thể xảy ra? Không có chính sách nguồn gốc chéo nào được triển khai trong các trình duyệt (ở đây: FF29 trên Linux)?

Tôi đang hỏi vì nếu websocket.org là xấu, nó có thể cố gắng giao tiếp với máy chủ WS cục bộ của tôi và chuyển hướng mọi thông báo nó nhận được từ localhost đến bất kỳ máy chủ nào khác:

Máy chủ WebSocket cục bộ Máy chủ Web xấu
tại ws: // localhost: 1234 tại http: //evil.tld
        | | |
        | | ------ [GET /] ---------> |
        | | <----- [HTML + EvilJS] ---- |
        | <------ [kết nối ws: // ..] ---- | |
        | <---- [một số thông tin liên lạc] -> | |
        | | ---- [ác trước] ----> |
        | | |

Tôi chưa kiểm tra toàn bộ trường hợp sử dụng, nhưng kết nối với ws: // localhost từ JS do websocket.org cung cấp chắc chắn hoạt động.


2
websocket.org không nên là xấu, các ổ cắm web có thể là vậy;)
kuldeep.kamboj

Câu trả lời:


51

Để giải quyết "Tại sao?" một phần, lý do tại sao các trình duyệt không thực thi Chính sách nguồn gốc giống nhau (trong đó CORS là thư giãn) cho WebSockets thay vì lệnh gọi AJAX, là vì WebSockets được giới thiệu sau khi giá trị của các yêu cầu nguồn gốc chéo được thiết lập và vì chúng ' không phải tuân theo SOP để bắt đầu, lý do lịch sử cho việc kiểm tra phía máy khách CORS không áp dụng.

Đối với AJAX, trong những ngày của Chính sách nguồn gốc chung, máy chủ không bao giờ mong đợi một trình duyệt đã xác thực gửi yêu cầu từ một miền khác 1 và do đó không cần đảm bảo yêu cầu đến từ một vị trí đáng tin cậy 2 , chỉ cần kiểm tra cookie phiên. Các thư giãn sau này như CORS phải có kiểm tra phía máy khách để tránh việc các ứng dụng hiện có bị lạm dụng do vi phạm giả định này (thực hiện một cách hiệu quả một cuộc tấn công CSRF ).

Nếu Web được phát minh ngày nay, theo như những gì chúng ta biết bây giờ, thì cả SOP và CORS đều không được yêu cầu đối với AJAX và có thể tất cả việc xác nhận sẽ được để lại cho máy chủ.

WebSockets, là một công nghệ mới hơn, được thiết kế để hỗ trợ các kịch bản miền chéo ngay từ đầu. Bất kỳ ai viết logic máy chủ nên nhận thức được khả năng xuất hiện các yêu cầu nguồn gốc chéo và thực hiện xác nhận cần thiết mà không cần các biện pháp phòng ngừa nặng nề từ phía trình duyệt à la CORS.


1 Đây là một sự đơn giản hóa. Yêu cầu GET có nguồn gốc chéo đối với tài nguyên (bao gồm các thẻ <img>, <link> và <script>) và yêu cầu POST gửi biểu mẫu luôn được cho phép như một tính năng cơ bản của Web. Ngày nay, các lệnh gọi AJAX có nguồn gốc chéo mà các yêu cầu có cùng thuộc tính cũng được cho phép và được gọi là các yêu cầu có nguồn gốc chéo đơn giản . Tuy nhiên, việc truy cập dữ liệu trả về từ các yêu cầu như vậy trong mã không được phép trừ khi được tiêu đề CORS của máy chủ cho phép rõ ràng. Ngoài ra, chính các yêu cầu POST "đơn giản" này là lý do chính tại sao mã thông báo chống CSRF lại cần thiết cho các máy chủ để tự bảo vệ mình khỏi các trang web độc hại.

2 Trên thực tế, một cách an toàn để kiểm tra nguồn yêu cầu thậm chí còn không có sẵn vì Referertiêu đề có thể bị giả mạo, ví dụ như sử dụng lỗ hổng chuyển hướng mở. Điều này cũng cho thấy các lỗ hổng CSRF được hiểu kém như thế nào vào thời điểm đó.


6
Điều này thực sự trả lời câu hỏi, vì vậy +1. Nhưng, đối với hồ sơ, tôi hoàn toàn không đồng ý với lập luận này. Tôi dự đoán rằng do quyết định thiết kế này, một số lượng đáng kể các trang web sử dụng WebSockets sẽ không thể xác thực Origintiêu đề và do đó, dữ liệu người dùng riêng tư bị rò rỉ cho các trang web của bên thứ ba. Khách hàng kiểm tra Access-Control-Allow-Origintiêu đề, giống như trước khi cho phép JS truy cập vào các phản hồi cho bất kỳ yêu cầu HTTP chéo nguồn nào khác trên web, sẽ là một cách đơn giản để ngăn chặn toàn bộ lớp tấn công này (Cross-Site WebSocket Hijacking). Quá muộn rồi.
Ajedi32

3
Tôi có xu hướng đồng ý rằng, thay đổi thiết kế về cơ bản là chuyển từ cách tiếp cận dựa trên danh sách trắng sang cách tiếp cận trong danh sách đen, điều này rất rủi ro. Điểm công bằng.
staafl

42

oberstet đã trả lời câu hỏi . Cảm ơn bạn! Rất tiếc, tôi không thể đánh dấu nó là "đúng" vì đó là một nhận xét. Trình duyệt gửi tiêu đề "origin" mà ứng dụng có thể kiểm tra.

Trong Java [1]:

@Ghi đè
public void onOpen (WebSocket clientSocket, bắt tay ClientHandshake) {
    String clientOrigin = handshake.getFieldValue ("origin");

    if (clientOrigin == null ||! clientOrigin.equals (WEBSOCKET_ALLOWED_ORIGIN_HEADER)) {
        logger.log (Level.WARNING, "Máy khách đã không gửi đúng tiêu đề gốc:" + clientOrigin);        

        clientSocket.close ();
        trở về;
    }

    // ...
}

[1] sử dụng https://github.com/TooTallNate/Java-WebSocket


OWASP đề cập đến việc kiểm tra tiêu đề Nguồn gốc (và có thể là Người giới thiệu) trong bảng gian lận CSRF của họ là bước đầu tiên và quan trọng nhất, nhưng họ cũng khuyên bạn nên tiến thêm một bước và thực hiện biện pháp bảo vệ cụ thể cho CSRF. Trong trường hợp của WebSockets, điều này có thể đang thêm mã thông báo chống truy vấn XSRF vào WS URI dưới dạng tham số truy vấn và xác thực nó ở phía máy chủ sau khi kiểm tra nguồn gốc.
Kevin Secrist

18

WebSocket có thể giao tiếp giữa các miền và chúng không bị giới hạn bởi SOP (Chính sách nguồn gốc giống nhau).

Vấn đề bảo mật tương tự mà bạn đã mô tả có thể xảy ra mà không có WebSockets.

JS ác có thể:

  • Tạo thẻ script / image có URL tới evil.tld và đưa dữ liệu vào chuỗi truy vấn.
  • Tạo thẻ biểu mẫu, đặt dữ liệu vào các trường và gọi hành động "gửi" của biểu mẫu, thực hiện HTTP POST, có thể là miền chéo. AJAX bị giới hạn bởi SOP, nhưng HTTP POST thông thường thì không. Kiểm tra vấn đề bảo mật web XSRF.

Nếu có thứ gì đó chèn javascript vào trang của bạn hoặc bạn nhận được javascript độc hại, bảo mật của bạn đã bị hỏng.


1
Tôi không lo lắng về JS xấu xa. Tôi biết rằng điều này luôn luôn có thể. Điều tôi thực sự lo ngại là sự cố trình duyệt: Bất kỳ trang web nào giờ đây đều có thể giao tiếp với một ổ cắm WS liên kết cục bộ và lấy cắp dữ liệu từ đó.
binwiederhier

53
SOP / CORS không áp dụng cho WebSocket, nhưng các trình duyệt sẽ gửi một origintiêu đề có chứa tên máy chủ của máy chủ đã phân phát HTML với JS đã mở kết nối WebSocket. Máy chủ WebSocket sau đó có thể hạn chế quyền truy cập bằng cách kiểm tra origin.
oberstet

Điều này không trả lời câu hỏi. Câu hỏi đặt ra là tại sao một trang web từ một miền khác lại có thể truy cập một WebSocket cục bộ. Trong kịch bản OPs, không có gì "đưa javascript vào trang của bạn" - đó là một kịch bản khác. Nếu không có WebSocket, một trang web từ xa sẽ không thể đọc tài nguyên trên máy chủ cục bộ, vì đó chính là điều mà SOP ngăn cản.
sleske
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.