From db956183e5b5d5adf457c5bdab9860bc60083357 Mon Sep 17 00:00:00 2001 From: Ryan Emmons <75249740+the-emmon@users.noreply.github.com> Date: Mon, 24 Jan 2022 18:08:14 -0600 Subject: [PATCH 1/2] Remediating a previously reported issue Reachable assertion DoS, affects most Nim web frameworks. --- src/httpbeast.nim | 1 - 1 file changed, 1 deletion(-) diff --git a/src/httpbeast.nim b/src/httpbeast.nim index cfaaff7..604f346 100644 --- a/src/httpbeast.nim +++ b/src/httpbeast.nim @@ -191,7 +191,6 @@ proc bodyInTransit(data: ptr Data): bool = var trueLen = parseContentLength(data.data, start=0) let bodyLen = data.data.len - data.headersFinishPos - assert(not (bodyLen > trueLen)) return bodyLen != trueLen var requestCounter: uint = 0 From 3fec275be0dc537510de65e8c4e17eef661d17be Mon Sep 17 00:00:00 2001 From: Ryan Emmons <75249740+the-emmon@users.noreply.github.com> Date: Tue, 25 Jan 2022 23:43:57 -0600 Subject: [PATCH 2/2] An update to the proposed DoS remediation After trying a handful of different approaches, including raising exceptions and sanitizing `Content-Length`, this seems to work the best. In addition to functional changes, the `trueLen` variable, set by the user-spoofable `Content-Length` header, has been renamed to `headerContentLength` to avoid confusion. --- src/httpbeast.nim | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/httpbeast.nim b/src/httpbeast.nim index 604f346..50cafda 100644 --- a/src/httpbeast.nim +++ b/src/httpbeast.nim @@ -188,10 +188,10 @@ proc bodyInTransit(data: ptr Data): bool = if data.headersFinishPos == -1: return false - var trueLen = parseContentLength(data.data, start=0) + var headerContentLength = parseContentLength(data.data, start=0) let bodyLen = data.data.len - data.headersFinishPos - return bodyLen != trueLen + return bodyLen != headerContentLength var requestCounter: uint = 0 proc genRequestID(): uint = @@ -476,14 +476,6 @@ proc body*(req: Request): Option[string] = pos .. ^1 ].some() - when not defined(release): - let length = - if req.headers.get().hasKey("Content-Length"): - req.headers.get()["Content-Length"].parseInt() - else: - 0 - assert result.get().len == length - proc ip*(req: Request): string = ## Retrieves the IP address that the request was made from. req.selector.getData(req.client).ip