Skip to content

Commit

Permalink
PDP-1526 Remove parts of the cookies that are not valid according to …
Browse files Browse the repository at this point in the history
…RFC 6265
  • Loading branch information
benjben committed Nov 12, 2024
1 parent 202a937 commit e494f56
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* Copyright (c) 2013-present Snowplow Analytics Ltd.
* All rights reserved.
*
* This software is made available by Snowplow Analytics, Ltd.,
* under the terms of the Snowplow Limited Use License Agreement, Version 1.0
* located at https://docs.snowplow.io/limited-use-license-1.0
* BY INSTALLING, DOWNLOADING, ACCESSING, USING OR DISTRIBUTING ANY PORTION
* OF THE SOFTWARE, YOU AGREE TO THE TERMS OF SUCH LICENSE AGREEMENT.
*/
package com.snowplowanalytics.snowplow.collector.core

object Rfc6265Cookie {

// See https://www.ietf.org/rfc/rfc6265.txt
private val allowedChars = Set(0x21.toChar) ++
Set(0x23.toChar to 0x2b.toChar: _*) ++
Set(0x2d.toChar to 0x3a.toChar: _*) ++
Set(0x3c.toChar to 0x5b.toChar: _*) ++
Set(0x5d.toChar to 0x7e.toChar: _*)

// Remove all the sub-parts (between two ';') that contain unauthorized characters
def parse(rawCookie: String): Option[String] =
rawCookie.replaceAll(" ", "").split(";").filter(_.forall(allowedChars.contains)).mkString(";") match {
case s if s.nonEmpty => Some(s)
case _ => None
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ class Service[F[_]: Sync](
case ci"X-Forwarded-For" | ci"X-Real-Ip" | ci"Cookie" if spAnonymous.isDefined => None
// FIXME: This is a temporary backport of old akka behaviour we will remove by
// adapting enrich to support a CIString header names as per RFC7230#Section-3.2
case ci"Cookie" => Some(s"Cookie: ${h.value}")
case ci"Cookie" => Rfc6265Cookie.parse(h.value).map(c => s"Cookie: $c")
case _ => Some(h.toString())
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.snowplowanalytics.snowplow.collector.core

import org.specs2.mutable.Specification

class Rfc6265CookieSpec extends Specification {
val valid1 = "name=value"
val valid2 = "name1=value2"
val bothValid = s"$valid1;$valid2"
val invalid = "{\"key\": \"value\"}"

"Rfc6265Cookie.parse" should {
"leave a valid cookie as is" in {
Rfc6265Cookie.parse(valid1) must beSome(valid1)
Rfc6265Cookie.parse(bothValid) must beSome(bothValid)
}

"remove whitespaces" in {
Rfc6265Cookie.parse(s" $valid1 ") must beSome(valid1)
Rfc6265Cookie.parse("name = value") must beSome(valid1)
}

"remove invalid parts" in {
Rfc6265Cookie.parse(s"$invalid;$valid1;$valid2") must beSome(bothValid)
Rfc6265Cookie.parse(s"$valid1;$invalid;$valid2") must beSome(bothValid)
Rfc6265Cookie.parse(s"$valid1;$valid2;$invalid") must beSome(bothValid)
}

"return None if no valid part is left" in {
Rfc6265Cookie.parse(invalid) must beNone
Rfc6265Cookie.parse(s";$invalid;") must beNone
Rfc6265Cookie.parse(";") must beNone
Rfc6265Cookie.parse(";;") must beNone
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ class ServiceSpec extends Specification {
"Content-Type: application/json",
"X-Forwarded-For: 192.0.2.3",
"Access-Control-Allow-Credentials: true",
"Cookie: cookie=value; sp=dfdb716e-ecf9-4d00-8b10-44edfbc8a108",
"Cookie: cookie=value;sp=dfdb716e-ecf9-4d00-8b10-44edfbc8a108",
"image/gif"
).asJava
e.contentType shouldEqual "image/gif"
Expand Down

0 comments on commit e494f56

Please sign in to comment.