From a6df370bd91b2ed7b13e68916e62d59b10acf759 Mon Sep 17 00:00:00 2001
From: Shivaram Lingamneni <slingamn@cs.stanford.edu>
Date: Sun, 30 Mar 2025 21:33:06 -0400
Subject: [PATCH] block HTTP DoS attacks (#2239)

Block uses of the JS Fetch API to send HTTP message bodies that are also valid
IRC. The constraint on such messages is that they must begin with a valid HTTP
verb; we can detect this and reject them immediately.
---
 irc/client.go | 6 +++++-
 irc/server.go | 2 ++
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/irc/client.go b/irc/client.go
index 6d2d4862..9598bf28 100644
--- a/irc/client.go
+++ b/irc/client.go
@@ -727,8 +727,12 @@ func (client *Client) run(session *Session) {
 			}
 			session.fakelag.Touch(command)
 		} else {
-			// DoS hardening, #505
+			if session.registrationMessages == 0 && httpVerbs.Has(msg.Command) {
+				client.Send(nil, client.server.name, ERR_UNKNOWNERROR, msg.Command, "This is not an HTTP server")
+				break
+			}
 			session.registrationMessages++
+			// DoS hardening, #505
 			if client.server.Config().Limits.RegistrationMessages < session.registrationMessages {
 				client.Send(nil, client.server.name, ERR_UNKNOWNERROR, "*", client.t("You have sent too many registration messages"))
 				break
diff --git a/irc/server.go b/irc/server.go
index fbc69415..9a3dd2a0 100644
--- a/irc/server.go
+++ b/irc/server.go
@@ -63,6 +63,8 @@ var (
 	chanTypes = "#"
 
 	throttleMessage = "You have attempted to connect too many times within a short duration. Wait a while, and you will be able to connect."
+
+	httpVerbs = utils.SetLiteral("CONNECT", "DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT", "TRACE")
 )
 
 // Server is the main Oragono server.