CVE-2019-17513: Improper Neutralization of Special Elements in Output Used by a Downstream Component ('Injection') (CWE-74)
value: An issue was discovered in Ratpack before 1.7.5. Due to a misuse of the Netty library class DefaultHttpHeaders, there is no validation that headers lack HTTP control characters. Thus, if untrusted data is used to construct HTTP headers with Ratpack, HTTP Response Splitting can occur.
CWE description: The product constructs all or part of a command, data structure, or record using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify how it is parsed or interpreted when it is sent to a downstream component.
CVSS v3 base score: 7.5
Published: 2019-10-18T03:15Z
Repository: https://github.com/ratpack/ratpack
Language: Other
Files changed: ratpack-core/src/test/groovy/ratpack/http/ResponseHeaderValidationSpec.groovy
Commit date: 2019-10-09 09:43:23 +1000
Commit message: Add test for response header validation

Diff: diff --git a/ratpack-core/src/test/groovy/ratpack/http/ResponseHeaderValidationSpec.groovy b/ratpack-core/src/test/groovy/ratpack/http/ResponseHeaderValidationSpec.groovy
new file mode 100644
index 000000000..d68aab26a
--- /dev/null
+++ b/ratpack-core/src/test/groovy/ratpack/http/ResponseHeaderValidationSpec.groovy
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2019 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ratpack.http
+
+import ratpack.test.internal.RatpackGroovyDslSpec
+
+class ResponseHeaderValidationSpec extends RatpackGroovyDslSpec {
+
+  def "invalid header values yield exception"() {
+    when:
+    handlers {
+      all {
+        try {
+          header("Test", "value\r\nAnotherHeader: another value")
+          render "ok"
+        } catch (e) {
+          render e.toString()
+        }
+      }
+    }
+
+    then:
+    def response = get()
+    response.headers.names == ['content-type', 'content-length'].toSet()
+    response.body.text == "java.lang.IllegalArgumentException: only ' ' and '\\t' are allowed after '\\n': value\r\nAnotherHeader: another value"
+  }
+
+}

Fixed code: /*
 * Copyright 2019 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package ratpack.http

import ratpack.test.internal.RatpackGroovyDslSpec

class ResponseHeaderValidationSpec extends RatpackGroovyDslSpec {

  def "invalid header values yield exception"() {
    when:
    handlers {
      all {
        try {
          header("Test", "value\r\nAnotherHeader: another value")
          render "ok"
        } catch (e) {
          render e.toString()
        }
      }
    }

    then:
    def response = get()
    response.headers.names == ['content-type', 'content-length'].toSet()
    response.body.text == "java.lang.IllegalArgumentException: only ' ' and '\\t' are allowed after '\\n': value\r\nAnotherHeader: another value"
  }

}