Skip to content

Commit

Permalink
fix CLRF
Browse files Browse the repository at this point in the history
  • Loading branch information
varshith257 committed Sep 28, 2024
1 parent 8ea35a2 commit 74175b1
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 26 deletions.
23 changes: 11 additions & 12 deletions zio-http/jvm/src/test/scala/zio/http/ConformanceSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@ object ConformanceSpec extends ZIOSpecDefault {
* Stock, presented at the 19th ACM Asia Conference on Computer and
* Communications Security (ASIA CCS) 2024.
*
* Paper URL: https://doi.org/10.1145/3634737.3637678
* GitHub Project: https://github.com/cispa/http-conformance
*
* Paper URL: https://doi.org/10.1145/3634737.3637678 GitHub Project:
* https://github.com/cispa/http-conformance
*/

val validUrl = URL.decode("http://example.com").toOption.getOrElse(URL.root)
Expand Down Expand Up @@ -1160,15 +1159,15 @@ object ConformanceSpec extends ZIOSpecDefault {
.addHeader(Header.XFrameOptions.SameOrigin),
),
// need test fail assertion something like this
// request.headers.get(Header.IfModifiedSince.name) match {
// case Some(_) =>
// Response.status(Status.NotModified).addHeader(Header.ContentLength(14)).copy(body = Body.empty)
// case None =>
// Response
// .status(Status.Ok)
// .addHeader(Header.ContentLength(14))
// .copy(body = Body.fromString("<div>ABC</div>"))
// }
// request.headers.get(Header.IfModifiedSince.name) match {
// case Some(_) =>
// Response.status(Status.NotModified).addHeader(Header.ContentLength(14)).copy(body = Body.empty)
// case None =>
// Response
// .status(Status.Ok)
// .addHeader(Header.ContentLength(14))
// .copy(body = Body.fromString("<div>ABC</div>"))
// }
)
for {
response <- app.runZIO(Request.get("/test"))
Expand Down
13 changes: 0 additions & 13 deletions zio-http/shared/src/main/scala/zio/http/Header.scala
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,6 @@ sealed trait Header {

object Header {

def validateHeaders(headers: Headers): ZIO[Any, Response, Unit] = {
val invalidHeaderChars = Set('\r', '\n', '\u0000')
val hasInvalidChar = headers.toList.exists { header =>
header.renderedValue.exists(invalidHeaderChars.contains)
}

if (hasInvalidChar) {
ZIO.fail(Response.status(Status.BadRequest))
} else {
ZIO.unit
}
}

sealed trait HeaderType {
type HeaderValue <: Header

Expand Down
32 changes: 31 additions & 1 deletion zio-http/shared/src/main/scala/zio/http/Routes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ final case class Routes[-Env, +Err](routes: Chunk[zio.http.Route[Env, Err]]) { s
val tree = self.tree
Handler
.fromFunctionHandler[Request] { req =>
Header.validateHeaders(req.headers) *> {
validateHostHeader(req).flatMap { _ =>
val chunk = tree.get(req.method, req.path)
val allowedMethods = tree.getAllMethods(req.path)

Expand Down Expand Up @@ -321,6 +321,36 @@ final case class Routes[-Env, +Err](routes: Chunk[zio.http.Route[Env, Err]]) { s
// }
// }

private def validateHostHeader(req: Request): Handler[Any, Response, Request, Response] = {
// val invalidHostChars = Set('\r', '\n', '\u0000')
val validHostRegex = """^[a-zA-Z0-9.-]+$""".r // RFC-1123 valid host pattern

// Extract all the host headers
val hostHeaders = req.headers.collect {
case h if h.headerName.equalsIgnoreCase("Host") => h.renderedValue
}

// Case 1: No Host header
if (hostHeaders.isEmpty) {
Handler.status(Status.BadRequest)
}
// Case 2: Multiple Host headers
else if (hostHeaders.length > 1) {
Handler.status(Status.BadRequest)
}
// Case 3: Host header contains invalid characters
// else if (hostHeaders.exists(value => value.exists(invalidHostChars.contains))) {
// Handler.status(Status.BadRequest)
// }
else if (!validHostRegex.matches(hostHeaders.head)) {
Handler.status(Status.BadRequest)
}
// Host header is valid
else {
Handler.ok
}
}

}

object Routes extends RoutesCompanionVersionSpecific {
Expand Down

0 comments on commit 74175b1

Please sign in to comment.