diff options
Diffstat (limited to 'backends')
-rw-r--r-- | backends/networking/sdl_net/client.cpp | 45 | ||||
-rw-r--r-- | backends/networking/sdl_net/client.h | 4 | ||||
-rw-r--r-- | backends/networking/sdl_net/localwebserver.cpp | 4 |
3 files changed, 50 insertions, 3 deletions
diff --git a/backends/networking/sdl_net/client.cpp b/backends/networking/sdl_net/client.cpp index 2af940c232..8ab9ed385e 100644 --- a/backends/networking/sdl_net/client.cpp +++ b/backends/networking/sdl_net/client.cpp @@ -60,11 +60,12 @@ void Client::readHeaders() { int bytes = SDLNet_TCP_Recv(_socket, buffer, BUFFER_SIZE); if (bytes <= 0) { warning("Client::readHeaders recv fail"); - _state = INVALID; + close(); return; - } + } _headers += Common::String(buffer, bytes); checkIfHeadersEnded(); + checkIfBadRequest(); } void Client::checkIfHeadersEnded() { @@ -73,6 +74,46 @@ void Client::checkIfHeadersEnded() { if (position) _state = READ_HEADERS; } +void Client::checkIfBadRequest() { + if (_state != READING_HEADERS) return; + uint32 headersSize = _headers.size(); + bool bad = false; + + const uint32 SUSPICIOUS_HEADERS_SIZE = 128 * 1024; + if (headersSize > SUSPICIOUS_HEADERS_SIZE) bad = true; + + if (!bad) { + if (headersSize > 0) { + const char *cstr = _headers.c_str(); + const char *position = strstr(cstr, "\r\n"); + if (position) { //we have at least one line - and we want the first one + //"<METHOD> <path> HTTP/<VERSION>\r\n" + Common::String method, path, http, buf; + for (uint32 i = 0; i < headersSize; ++i) { + if (_headers[i] == ' ') { + if (method == "") method = buf; + else if (path == "") path = buf; + else if (http == "") http = buf; + else { + bad = true; + break; + } + buf = ""; + } else buf += _headers[i]; + } + + //check that method is supported + if (method != "GET" && method != "PUT" && method != "POST") bad = true; + + //check that HTTP/<VERSION> is OK + if (!http.hasPrefix("HTTP/")) bad = true; + } + } + } + + if (bad) _state = BAD_REQUEST; +} + void Client::close() { if (_set) { if (_socket) { diff --git a/backends/networking/sdl_net/client.h b/backends/networking/sdl_net/client.h index 74c700e447..7f78947223 100644 --- a/backends/networking/sdl_net/client.h +++ b/backends/networking/sdl_net/client.h @@ -34,7 +34,8 @@ namespace Networking { enum ClientState { INVALID, READING_HEADERS, - READ_HEADERS + READ_HEADERS, + BAD_REQUEST }; class Client { @@ -44,6 +45,7 @@ class Client { Common::String _headers; void checkIfHeadersEnded(); + void checkIfBadRequest(); public: Client(); diff --git a/backends/networking/sdl_net/localwebserver.cpp b/backends/networking/sdl_net/localwebserver.cpp index 783814de14..ee67f787c3 100644 --- a/backends/networking/sdl_net/localwebserver.cpp +++ b/backends/networking/sdl_net/localwebserver.cpp @@ -128,6 +128,10 @@ void LocalWebserver::handleClient(uint32 i) { warning("headers %s", _client[i].headers().c_str()); _client[i].close(); break; + case BAD_REQUEST: + //TODO: answer with BAD REQUEST + _client[i].close(); + break; } } |