From e1a0ce5af94cdb77e689916e730a655ea0ec823c Mon Sep 17 00:00:00 2001 From: Houkime Date: Thu, 2 Jan 2020 14:02:29 +0000 Subject: [PATCH] Prevent GDScript language server from listening to external hosts by default * Add bind_ip property to WebSocketServer defaulting to "*" (listen to everyone) * Set default for GDscript Language Server to listen only to localhost Fixes potential security issue with GDScript language server being exposed to the broad net by default. Since it is the server which primary usage is to provide utility to the local editor there is no need to expose it. --- .../gdscript_language_protocol.cpp | 3 ++- .../language_server/gdscript_language_protocol.h | 2 +- .../language_server/gdscript_language_server.cpp | 2 +- modules/websocket/doc_classes/WebSocketServer.xml | 3 +++ modules/websocket/websocket_server.cpp | 15 +++++++++++++++ modules/websocket/websocket_server.h | 5 +++++ modules/websocket/wsl_server.cpp | 2 +- 7 files changed, 28 insertions(+), 4 deletions(-) diff --git a/modules/gdscript/language_server/gdscript_language_protocol.cpp b/modules/gdscript/language_server/gdscript_language_protocol.cpp index cff7653d3ac..7133c6b4be2 100644 --- a/modules/gdscript/language_server/gdscript_language_protocol.cpp +++ b/modules/gdscript/language_server/gdscript_language_protocol.cpp @@ -156,7 +156,7 @@ void GDScriptLanguageProtocol::poll() { server->poll(); } -Error GDScriptLanguageProtocol::start(int p_port) { +Error GDScriptLanguageProtocol::start(int p_port, const IP_Address &p_bind_ip) { if (server == NULL) { server = dynamic_cast(ClassDB::instance("WebSocketServer")); ERR_FAIL_COND_V(!server, FAILED); @@ -165,6 +165,7 @@ Error GDScriptLanguageProtocol::start(int p_port) { server->connect("client_connected", this, "on_client_connected"); server->connect("client_disconnected", this, "on_client_disconnected"); } + server->set_bind_ip(p_bind_ip); return server->listen(p_port); } diff --git a/modules/gdscript/language_server/gdscript_language_protocol.h b/modules/gdscript/language_server/gdscript_language_protocol.h index e45db274e9e..52c680ab199 100644 --- a/modules/gdscript/language_server/gdscript_language_protocol.h +++ b/modules/gdscript/language_server/gdscript_language_protocol.h @@ -77,7 +77,7 @@ public: _FORCE_INLINE_ bool is_initialized() const { return _initialized; } void poll(); - Error start(int p_port); + Error start(int p_port, const IP_Address &p_bind_ip); void stop(); void notify_all_clients(const String &p_method, const Variant &p_params = Variant()); diff --git a/modules/gdscript/language_server/gdscript_language_server.cpp b/modules/gdscript/language_server/gdscript_language_server.cpp index 19bb3ed1ee5..7170c630582 100644 --- a/modules/gdscript/language_server/gdscript_language_server.cpp +++ b/modules/gdscript/language_server/gdscript_language_server.cpp @@ -84,7 +84,7 @@ void GDScriptLanguageServer::thread_main(void *p_userdata) { void GDScriptLanguageServer::start() { port = (int)_EDITOR_GET("network/language_server/remote_port"); use_thread = (bool)_EDITOR_GET("network/language_server/use_thread"); - if (protocol.start(port) == OK) { + if (protocol.start(port, IP_Address("127.0.0.1")) == OK) { EditorNode::get_log()->add_message("--- GDScript language server started ---", EditorLog::MSG_TYPE_EDITOR); if (use_thread) { ERR_FAIL_COND(thread != NULL); diff --git a/modules/websocket/doc_classes/WebSocketServer.xml b/modules/websocket/doc_classes/WebSocketServer.xml index f5fb77f3a18..cd47c10f80f 100644 --- a/modules/websocket/doc_classes/WebSocketServer.xml +++ b/modules/websocket/doc_classes/WebSocketServer.xml @@ -83,6 +83,9 @@ + + When not set to [code]*[/code] will restrict incoming connections to the specified IP address. Setting [code]bind_ip[/code] to [code]127.0.0.1[/code] will cause the server to listen only to the local host. + When using SSL (see [member private_key] and [member ssl_certificate]), you can set this to a valid [X509Certificate] to be provided as additional CA chain information during the SSL handshake. diff --git a/modules/websocket/websocket_server.cpp b/modules/websocket/websocket_server.cpp index ded18508461..76e88d72b9a 100644 --- a/modules/websocket/websocket_server.cpp +++ b/modules/websocket/websocket_server.cpp @@ -34,6 +34,7 @@ GDCINULL(WebSocketServer); WebSocketServer::WebSocketServer() { _peer_id = 1; + bind_ip = IP_Address("*"); } WebSocketServer::~WebSocketServer() { @@ -49,6 +50,10 @@ void WebSocketServer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_peer_port", "id"), &WebSocketServer::get_peer_port); ClassDB::bind_method(D_METHOD("disconnect_peer", "id", "code", "reason"), &WebSocketServer::disconnect_peer, DEFVAL(1000), DEFVAL("")); + ClassDB::bind_method(D_METHOD("get_bind_ip"), &WebSocketServer::get_bind_ip); + ClassDB::bind_method(D_METHOD("set_bind_ip"), &WebSocketServer::set_bind_ip); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "bind_ip"), "set_bind_ip", "get_bind_ip"); + ClassDB::bind_method(D_METHOD("get_private_key"), &WebSocketServer::get_private_key); ClassDB::bind_method(D_METHOD("set_private_key"), &WebSocketServer::set_private_key); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "private_key", PROPERTY_HINT_RESOURCE_TYPE, "CryptoKey", 0), "set_private_key", "get_private_key"); @@ -67,6 +72,16 @@ void WebSocketServer::_bind_methods() { ADD_SIGNAL(MethodInfo("data_received", PropertyInfo(Variant::INT, "id"))); } +IP_Address WebSocketServer::get_bind_ip() const { + return bind_ip; +} + +void WebSocketServer::set_bind_ip(const IP_Address &p_bind_ip) { + ERR_FAIL_COND(is_listening()); + ERR_FAIL_COND(!p_bind_ip.is_valid() && !p_bind_ip.is_wildcard()); + bind_ip = p_bind_ip; +} + Ref WebSocketServer::get_private_key() const { return private_key; } diff --git a/modules/websocket/websocket_server.h b/modules/websocket/websocket_server.h index bfdac114890..3ce4dbe711a 100644 --- a/modules/websocket/websocket_server.h +++ b/modules/websocket/websocket_server.h @@ -41,6 +41,8 @@ class WebSocketServer : public WebSocketMultiplayerPeer { GDCLASS(WebSocketServer, WebSocketMultiplayerPeer); GDCICLASS(WebSocketServer); + IP_Address bind_ip; + protected: static void _bind_methods(); @@ -67,6 +69,9 @@ public: void _on_disconnect(int32_t p_peer_id, bool p_was_clean); void _on_close_request(int32_t p_peer_id, int p_code, String p_reason); + IP_Address get_bind_ip() const; + void set_bind_ip(const IP_Address &p_bind_ip); + Ref get_private_key() const; void set_private_key(Ref p_key); diff --git a/modules/websocket/wsl_server.cpp b/modules/websocket/wsl_server.cpp index c98c62cce9a..c3dd79a89cf 100644 --- a/modules/websocket/wsl_server.cpp +++ b/modules/websocket/wsl_server.cpp @@ -165,7 +165,7 @@ Error WSLServer::listen(int p_port, const Vector p_protocols, bool gd_mp for (int i = 0; i < p_protocols.size(); i++) { pw[i] = p_protocols[i].strip_edges(); } - _server->listen(p_port); + _server->listen(p_port, bind_ip); return OK; }