2013-08-16 41 views
29

Trong phần 1.3 "Mở Handshake" của draft-ietf-hybi-thewebsocketprotocol-17, nó mô tả Sec-WebSocket-Key như sau:Sec-WebSocket-Key là gì?

Để chứng minh rằng cái bắt tay đã nhận được, máy chủ đã để mất hai mẩu thông tin và kết hợp chúng để tạo thành một phản ứng. Thông tin đầu tiên xuất phát từ | Sec-WebSocket-Key | lĩnh vực tiêu đề trong quá trình bắt tay khách hàng:

Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== 

Đối với lĩnh vực tiêu đề này, máy chủ đã để mất giá trị (như hiện nay trong lĩnh vực tiêu đề, ví dụ như base64 mã hóa [RFC4648] phiên bản trừ đi bất kỳ hàng đầu và dấu khoảng trắng) và nối nó với Mã định danh duy nhất toàn cầu (GUID, [RFC4122]) "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" ở dạng chuỗi, không được sử dụng bởi các điểm cuối mạng không hiểu giao thức WebSocket. Một hàm băm SHA-1 (160 bit), mã hóa base64 (xem Phần 4 của [RFC4648]), của phép nối này sau đó được trả về trong cái bắt tay của máy chủ [FIPS.180-2.2002].

Đây là điều tôi không thể hiểu được: tại sao không chỉ đơn giản là trả lại mã 101? Nếu việc sử dụng thích hợp Sec-WebSocket-Key là để bảo mật hoặc để chứng minh họ có thể xử lý các yêu cầu websocket, thì bất kỳ máy chủ nào cũng có thể trả về khóa dự kiến ​​nếu họ muốn và giả sử chúng là máy chủ WebSocket.

Trả lời

18

Theo RFC 6455 tiêu chuẩn WebSocket

first part:

.. the server has to prove to the client that it received the 
client's WebSocket handshake, so that the server doesn't accept 
connections that are not WebSocket connections. This prevents an 
attacker from tricking a WebSocket server by sending it carefully 
crafted packets using XMLHttpRequest [XMLHttpRequest] or a form 
submission. 

... 
For this header field, the server has to take the value (as present 
in the header field, e.g., the base64-encoded [RFC4648] version minus 
any leading and trailing whitespace) and concatenate this with the 
Globally Unique Identifier (GUID, [RFC4122]) "258EAFA5-E914-47DA- 
95CA-C5AB0DC85B11" in string form, which is unlikely to be used by 
network endpoints that do not understand the WebSocket Protocol. 

second part:

The |Sec-WebSocket-Key| header field is used in the WebSocket opening 
handshake. It is sent from the client to the server to provide part 
of the information used by the server to prove that it received a 
valid WebSocket opening handshake. This helps ensure that the server 
does not accept connections from non-WebSocket clients (e.g., HTTP 
clients) that are being abused to send data to unsuspecting WebSocket 
servers. 

Vì vậy, khi giá trị của GUID được quy định trong tiêu chuẩn, nó là khó (có thể, đặt với xác suất rất nhỏ) rằng máy chủ không nhận thức được Websockets wil Tôi sử dụng nó. Nó không cung cấp bất kỳ bảo mật nào (các websockets an toàn - wss: // - does), nó chỉ đảm bảo rằng máy chủ hiểu giao thức websockets. Thực sự, như bạn đã đề cập, nếu bạn biết về các ổ cắm web (đó là những gì cần kiểm tra), bạn có thể giả vờ làm máy chủ websocket bằng cách gửi trả lời đúng. Nhưng sau đó, nếu bạn sẽ không hoạt động chính xác (ví dụ: các khung hình chính xác), nó sẽ được coi là vi phạm giao thức. Trên thực tế, bạn có thể viết máy chủ websocket không đúng, nhưng sẽ không có nhiều sử dụng trong đó.

Và một mục đích khác là để ngăn chặn các khách hàng vô tình yêu cầu nâng cấp web không mong đợi (nói, bằng cách thêm các tiêu đề tương ứng theo cách thủ công và sau đó mong đợi người khác). Sec-WebSocket-Key và các tiêu đề liên quan khác đều bị cấm sử dụng phương thức setRequestHeader trong trình duyệt.

+0

đúng là một số trường tiêu đề yêu cầu không thể sửa đổi được từ javascript trong XMLHttpRequest, vì vậy cách thức từ trình duyệt bị chặn? nhưng nếu có trình duyệt (có thể là phiên bản đầu) có thể cho phép sửa đổi trường khóa-websocket-key hoặc nếu yêu cầu được gửi bởi một chương trình để mô phỏng trình duyệt, bạn hoàn toàn có thể tự tạo tiêu đề yêu cầu, do đó làm Sec-WebSocket-Key không có ý nghĩa? – user2003548

+2

Vui lòng đọc lại câu trả lời của tôi. Ngay cả khi bạn viết máy chủ hoặc máy khách của bạn sẽ mô phỏng yêu cầu nâng cấp chính xác, bạn sẽ làm điều đó _intentionally_ với kiến ​​thức rằng giao thức Websockest * tồn tại *. Khóa-WebSocket-Key được sử dụng để lọc các yêu cầu _unintended_. Nếu bạn lo lắng về bảo mật - hãy sử dụng các ổ cắm web an toàn. –

+0

do đó giao thức được thiết kế dựa trên ppl sẽ sử dụng nó bình thường, nếu phải đối mặt với một nhà văn phần mềm độc hại, nó sẽ bị hỏng như http bình thường, tôi có hiểu không? – user2003548

1

Tôi có xu hướng đồng ý.

Không có điều gì quan trọng sẽ thay đổi nếu khách hàng bỏ qua giá trị của tiêu đề Sec-WebSocket-Accept.

Tại sao? Bởi vì máy chủ không chứng minh bất cứ điều gì bằng cách thực hiện phép tính này (ngoài việc nó có mã để thực hiện phép tính). Chỉ là về điều duy nhất nó quy định là một máy chủ mà chỉ đơn giản là trả lời với một phản ứng đóng hộp.

Việc trao đổi tiêu đề (ví dụ: với các giá trị 'khóa' cố định và 'chấp nhận') đã đủ để loại trừ bất kỳ kết nối ngẫu nhiên nào với ít nhất là cố gắng trở thành máy chủ WebSocket; và nếu nó đang cố gắng, yêu cầu mà nó thực hiện phép tính này khó có thể trở thành một trở ngại cho thành công của nó.

Các RFC tuyên bố:

" .. các máy chủ có để chứng minh cho khách hàng mà nó nhận được cái bắt tay WebSocket các của khách hàng, do đó máy chủ không chấp nhận kết nối mà không phải là WebSocket kết nối. "

và:

"Điều này giúp đảm bảo rằng các máy chủ không chấp nhận kết nối từ khách hàng không WebSocket .."

Cả những tuyên bố thực hiện bất kỳ ý nghĩa. Máy chủ không bao giờ là người từ chối kết nối bởi vì nó là một trong những máy tính băm, không phải là một trong những kiểm tra nó.

Loại trao đổi này sẽ có ý nghĩa nếu GUID ma thuật không được sửa, nhưng thay vào đó là bí mật được chia sẻ giữa máy khách và máy chủ. Trong trường hợp đó, việc trao đổi sẽ cho phép máy chủ chứng minh với khách hàng rằng nó có bí mật được chia sẻ mà không tiết lộ nó.

6

Chủ yếu là để chặn bộ nhớ cache.

Hãy tưởng tượng máy chủ proxy ngược trong suốt đang xem lưu lượng truy cập HTTP. Nếu nó không hiểu WS, nó có thể nhầm lẫn bộ nhớ cache một cái bắt tay WS và trả lời với một 101 vô dụng cho khách hàng tiếp theo.

Sử dụng nonce (khóa) và yêu cầu phản hồi thách thức cơ bản khá cụ thể đối với WS đảm bảo máy chủ thực sự hiểu đây là bắt tay WS và lần lượt nói với khách hàng rằng máy chủ thực sự sẽ lắng nghe trên cổng. Một proxy đảo ngược bộ nhớ đệm sẽ không bao giờ thực hiện logic băm đó "do nhầm lẫn".