为什么没有WebSockets的同源策略? 为什么我可以连接到ws:// localhost?

我想为我的应用程序使用WebSockets进行进程间通信(守护进程< – > WebGUI和守护进程< – > FatClient等)。 在testing期间,我尝试通过websocket.org上的JavaScript WebSocket客户端( http://www.websocket.org/echo.html )连接到本地运行的Web套接字服务器(ws:// localhost:1234)。

我现在的问题是:
为什么这可能? 在浏览器中是否没有实施跨源策略(这里是Linux上的FF29)?

我问,因为如果websocket.org是邪恶的,它可以尝试与我的本地WS服务器进行通信,并redirect它从本地收到的每个消息到任何其他服务器:

本地WebSocket服务器浏览器恶意Web服务器
在http://evil.tld的ws:// localhost:1234
         |  |  |
         |  | ------ [GET /] ---------> |
         |  | <----- [HTML + EvilJS] ---- |
         | <------ [连接ws:// ..] ---- |  |
         | <---- [某个通讯]  - > |  |
         |  | ---- [邪恶转] ----> |
         |  |  |

我没有testing整个用例,但是从websocket.org发布的JS连接到ws:// localhost肯定有效。

oberstet回答了这个问题 。 谢谢! 不幸的是,我不能把它标记为“正确”,因为这是一个评论。 浏览器发送可由应用程序检查的“origin”标题。

在Java [1]中:

  @覆盖
 public void onOpen(WebSocket clientSocket,ClientHandshake handshake){
     String clientOrigin = handshake.getFieldValue(“origin”);

     if(clientOrigin == null ||!clientOrigin.equals(WEBSOCKET_ALLOWED_ORIGIN_HEADER)){
         logger.log(Level.WARNING,“客户端没有发送正确的源头:”+ clientOrigin);        

         clientSocket.close();
        返回;
     }

     // ...
 } 

[1]使用https://github.com/TooTallNate/Java-WebSocket

解决“为什么?” 方面,浏览器为什么不强制WebSockets实现相同原点策略(和CORS放宽)而不是AJAX调用,原因是WebSocket是在跨源请求场景的价值build立很久之后引入的,而历史原因对于CORS客户端检查并不适用于他们。

最初,在AJAX的单一原始策略的时代,服务器从来没有期望从不同的域接收到浏览器authentication的请求,并且不需要检查Referer头来确保请求来自预期的源。 后来,像CORS这样的放宽必须要有客户端的检查,以避免违反他们的假设来破坏现有的应用程序。

如果networking是在今天发明的,知道我们现在知道什么,那么AJAX就不需要SOP和CORS,所有的validation都有可能留在服务器端。

同样,WebSocket是一个新的技术,意在支持跨域的场景。 任何编写服务器逻辑的人都应该意识到跨域请求的可能性,并执行必要的validation,而不需要使用浏览器端的严格的预防措施。

WebSockets可以跨域通信,并且不受SOP(同源策略)的限制。

您所描述的安全问题可能会在没有WebSocket的情况下发生。

邪恶的JS可以:

  • 创build一个URL为evil.tld的脚本/图像标签,并将数据放入查询string中。
  • 创build一个表单标签,将数据放在字段中,然后调用表单的“submit”操作,做一个可以跨域的HTTP POST。 AJAX受SOP的限制,但正常的HTTP POST不是。 检查XSRFnetworking安全问题。

如果有东西在您的页面中注入JavaScript,或者您获得了恶意JavaScript,则您的安全性已被破坏。