Skip to content

Commit 040230a

Browse files
committed
Merge pull request #499 from gaudryc/security/fix_remote_endpoint_exception_in_webserver
Fix a security issue (DOS) in webserver
2 parents 72945da + 55d283f commit 040230a

File tree

3 files changed

+41
-21
lines changed

3 files changed

+41
-21
lines changed

History.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ Version 2.4xxx
7979
- Fixed: Fix Security devices edit form by hiding Selector switch options (#473).
8080
- Fixed: Fix missing Selector switch levels in MQTT device info response by returning all device options (#459)
8181
- Fixed: Fix dead code in the AsyncSerial::close method causing the method not to stop or close the background resources.
82+
- Fixed: Fix a security issue (DOS) in webserver to prevent a remote_endpoint exception to be thrown to the WebServer class causing the webserver to be down (no possible stop and no possible connection). Now, the webserver can be scanned using the nmap tool (for the SSL configuration purpose).
8283
- Updated: OpenZWave, configuration files
8384

8485
Version 2.3530 (November 1th 2015)

webserver/connection.cpp

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,20 +75,30 @@ boost::asio::ip::tcp::socket& connection::socket()
7575

7676
void connection::start()
7777
{
78-
host_endpoint_ = socket().remote_endpoint().address().to_string();
79-
if (secure_) {
78+
boost::system::error_code ec;
79+
boost::asio::ip::tcp::endpoint endpoint = socket().remote_endpoint(ec);
80+
if (ec) {
81+
// Prevent the exception to be thrown to run to avoid the server to be locked (still listening but no more connection or stop).
82+
// If the exception returns to WebServer to also create a exception loop.
83+
_log.Log(LOG_ERROR,"Getting error '%s' while getting remote_endpoint in connection::start", ec.message().c_str());
84+
connection_manager_.stop(shared_from_this());
85+
return;
86+
}
87+
88+
host_endpoint_ = endpoint.address().to_string();
89+
if (secure_) {
8090
#ifdef NS_ENABLE_SSL
8191
// with ssl, we first need to complete the handshake before reading
82-
sslsocket_->async_handshake(boost::asio::ssl::stream_base::server,
83-
boost::bind(&connection::handle_handshake, shared_from_this(),
84-
boost::asio::placeholders::error));
92+
sslsocket_->async_handshake(boost::asio::ssl::stream_base::server,
93+
boost::bind(&connection::handle_handshake, shared_from_this(),
94+
boost::asio::placeholders::error));
8595
#endif
86-
}
87-
else {
96+
}
97+
else {
8898
// start reading data
8999
read_more();
90-
}
91-
m_lastresponse=mytime(NULL);
100+
}
101+
m_lastresponse=mytime(NULL);
92102
}
93103

94104
void connection::stop()

webserver/connection_manager.cpp

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,30 @@ namespace server {
2020

2121
void connection_manager::start(connection_ptr c)
2222
{
23-
connections_.insert(c);
24-
std::string s = c->socket().remote_endpoint().address().to_string();
23+
connections_.insert(c);
2524

26-
if (s.substr(0, 7) == "::ffff:") {
27-
s = s.substr(7);
28-
}
25+
boost::system::error_code ec;
26+
boost::asio::ip::tcp::endpoint endpoint = c->socket().remote_endpoint(ec);
27+
if (ec) {
28+
// Prevent the exception to be thrown to run to avoid the server to be locked (still listening but no more connection or stop).
29+
// If the exception returns to WebServer to also create a exception loop.
30+
_log.Log(LOG_ERROR,"Getting error '%s' while getting remote_endpoint in connection_manager::start", ec.message().c_str());
31+
stop(c);
32+
return;
33+
}
2934

30-
if (connectedips_.find(s)==connectedips_.end())
31-
{
32-
//ok, this could get a very long list when running for years
33-
connectedips_.insert(s);
34-
_log.Log(LOG_STATUS,"Incoming connection from: %s", s.c_str());
35-
}
35+
std::string s = endpoint.address().to_string();
36+
if (s.substr(0, 7) == "::ffff:") {
37+
s = s.substr(7);
38+
}
39+
if (connectedips_.find(s) == connectedips_.end())
40+
{
41+
//ok, this could get a very long list when running for years
42+
connectedips_.insert(s);
43+
_log.Log(LOG_STATUS,"Incoming connection from: %s", s.c_str());
44+
}
3645

37-
c->start();
46+
c->start();
3847
}
3948

4049
void connection_manager::stop(connection_ptr c)

0 commit comments

Comments
 (0)