Browse Source

Merge pull request #876 from paullouisageneau/check-ws-http-method

Check WebSocket HTTP method to fail immediately on invalid input
Paul-Louis Ageneau 2 years ago
parent
commit
474cb236aa
3 changed files with 18 additions and 0 deletions
  1. 12 0
      src/impl/utils.cpp
  2. 3 0
      src/impl/utils.hpp
  3. 3 0
      src/impl/wshandshake.cpp

+ 12 - 0
src/impl/utils.cpp

@@ -128,4 +128,16 @@ std::seed_seq random_seed() {
 	return std::seed_seq(seed.begin(), seed.end());
 }
 
+bool IsHttpRequest(const byte *buffer, size_t size) {
+	// Check the buffer starts with a valid-looking HTTP method
+	for (size_t i = 0; i < size; ++i) {
+		char c = static_cast<char>(buffer[i]);
+		if (i > 0 && c == ' ')
+			break;
+		else if (i >= 8 || c < 'A' || c > 'Z')
+			return false;
+	}
+	return true;
+}
+
 } // namespace rtc::impl::utils

+ 3 - 0
src/impl/utils.hpp

@@ -32,6 +32,9 @@ string base64_encode(const binary &data);
 // Return a random seed sequence
 std::seed_seq random_seed();
 
+// Check the buffer contains the beginning of an HTTP request
+bool IsHttpRequest(const byte *buffer, size_t size);
+
 template <typename Generator, typename Result = typename Generator::result_type>
 struct random_engine_wrapper {
 	Generator &engine;

+ 3 - 0
src/impl/wshandshake.cpp

@@ -131,6 +131,9 @@ string WsHandshake::generateHttpError(int responseCode) {
 }
 
 size_t WsHandshake::parseHttpRequest(const byte *buffer, size_t size) {
+	if (!utils::IsHttpRequest(buffer, size))
+		throw RequestError("Invalid HTTP request for WebSocket", 400);
+
 	std::unique_lock lock(mMutex);
 	std::list<string> lines;
 	size_t length = parseHttpLines(buffer, size, lines);