Is web server server authentication secure?

I am using https://github.com/lemmingzshadow/php-websocket/

I can resolve some domains, and I resolved localhost and the domain that points to my local server. But I am wondering if someone else who has a server on their computer can connect to my websocket (through my domain) using a script on his localhost server.

Here is the relevant code:

-> server / server.php

 $server->setAllowedOrigin('localhost'); $server->setAllowedOrigin('mydomain.com'); 

-> server / lib / WebSocket / Connection.php

 // check origin: if($this->server->getCheckOrigin() === true) { $origin = (isset($headers['Sec-WebSocket-Origin'])) ? $headers['Sec-WebSocket-Origin'] : false; $origin = (isset($headers['Origin'])) ? $headers['Origin'] : $origin; if($origin === false) { $this->log('No origin provided.'); $this->sendHttpResponse(401); stream_socket_shutdown($this->socket, STREAM_SHUT_RDWR); $this->server->removeClientOnError($this); return false; } if(empty($origin)) { $this->log('Empty origin provided.'); $this->sendHttpResponse(401); stream_socket_shutdown($this->socket, STREAM_SHUT_RDWR); $this->server->removeClientOnError($this); return false; } if($this->server->checkOrigin($origin) === false) { $this->log('Invalid origin provided.'); $this->sendHttpResponse(401); stream_socket_shutdown($this->socket, STREAM_SHUT_RDWR); $this->server->removeClientOnError($this); return false; } } 

-> server /lib/WebSocket/Server.php

 public function checkOrigin($domain) { $domain = str_replace('http://', '', $domain); $domain = str_replace('https://', '', $domain); $domain = str_replace('www.', '', $domain); $domain = str_replace('/', '', $domain); return isset($this->_allowedOrigins[$domain]); } public function setAllowedOrigin($domain) { $domain = str_replace('http://', '', $domain); $domain = str_replace('www.', '', $domain); $domain = (strpos($domain, '/') !== false) ? substr($domain, 0, strpos($domain, '/')) : $domain; if(empty($domain)) { return false; } $this->_allowedOrigins[$domain] = true; return true; } 

Edit:

Perhaps I was not clear enough. I want everyone to be able to connect to websocket, but only if they are in my domain (or my local host), something like Same Origin Policy in AJAX.

My concern is that if I allow localhost, then possibly all other local hosts on other computers will be allowed too.

+6
source share
3 answers

Although I was worried about allowing connections from all local hosts, when I wanted to allow only my localhost, I found that in another question , kanaka said:

To clarify, Javascript runs in an uncompromising and well-organized browser that cannot affect the value of Sec-WebSocket-Origin, which contains the value of the source site on which the page was loaded (allowing the server to allow specific creation points). However, if you had Javascript running in Node.js as a WebSocket client, it can set the origin no matter what it wants. CORS security is for the security of browser users, not your server. You need other mechanisms to protect your server.

Then my origin verification code is not safe at all; and it doesn't matter if all local hosts allow everything, because if someone has enough knowledge to connect to my websocket using his own localhost, it is likely that he could change the Origin header.

+1
source

If you want to be sure, you must add IP verification by analyzing $_SERVER["REMOTE_ADDR"] . The origin that is being verified is a text value provided by the client that can be easily faked.

 if (!in_array($_SERVER["REMOTE_ADDR"], array("127.0.0.1", "ip.of.dom.ain")) exit; 

If you do not want to hardcode the IP address, or if this changes frequently, you can use gethostbyname to get the IP address for this domain. Keep in mind that this will add a delay for each request when DNS should be requested for the domain (s), and thus will cause timeouts when your DNS drops. (of course, the following code could be optimized)

 $allowed_origins = array('localhost', 'mydomain.com'); $allowed_ips = array(); foreach ($allowed_origins as $domain) { $server->setAllowedOrigin($domain); $allowed_ips[] = gethostbyname($domain); } if (!in_array($_SERVER["REMOTE_ADDR"], $allowed_ips)) exit; 

Probably the right way to do this is to protect your resource through your web server so that it only accepts requests from the IP addresses you want to allow (see deny in Apache or deny in nginx ).

+1
source

If you check the Origin header, this is enough to provide something like a policy of the same origin. The Origin header can be tampered with outside the browser in a custom application, such as the node WebSocket client, but it doesn’t matter, the same goes for regular HTTP requests. SOP is only browsers.

Therefore, checking the Origin header is not on access protection, but on CSRF protection. Invalid third-party sites will not be allowed to connect to your WebSocket endpoint (with automatic credentials) if the user is currently logged on.

0
source

All Articles