Signed-off-by: chixinze <xmdxcxz@gmail.com> (cherry picked from commit ac0cf1417005186b4542f7e56d6815605e6d2c5c)
60 lines
2.1 KiB
Diff
60 lines
2.1 KiB
Diff
From 9ca5b3628245e2878426602bb24f1a4e45edc850 Mon Sep 17 00:00:00 2001
|
|
From: "Robin H. Johnson" <rjohnson@digitalocean.com>
|
|
Date: Fri, 27 Mar 2020 20:48:13 +0100
|
|
Subject: [PATCH] rgw: reject control characters in response-header actions
|
|
|
|
S3 GetObject permits overriding response header values, but those inputs
|
|
need to be validated to insure only characters that are valid in an HTTP
|
|
header value are present.
|
|
|
|
Credit: Initial vulnerability discovery by William Bowling (@wcbowling)
|
|
Credit: Further vulnerability discovery by Robin H. Johnson <rjohnson@digitalocean.com>
|
|
Signed-off-by: Robin H. Johnson <rjohnson@digitalocean.com>
|
|
---
|
|
src/rgw/rgw_rest_s3.cc | 22 ++++++++++++++++++++++
|
|
1 file changed, 22 insertions(+)
|
|
|
|
diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc
|
|
index dc49caae18d..459dd1dc715 100644
|
|
--- a/src/rgw/rgw_rest_s3.cc
|
|
+++ b/src/rgw/rgw_rest_s3.cc
|
|
@@ -167,6 +167,15 @@ int decode_attr_bl_single_value(map<string, bufferlist>& attrs, const char *attr
|
|
return 0;
|
|
}
|
|
|
|
+inline bool str_has_cntrl(const std::string s) {
|
|
+ return std::any_of(s.begin(), s.end(), ::iscntrl);
|
|
+}
|
|
+
|
|
+inline bool str_has_cntrl(const char* s) {
|
|
+ std::string _s(s);
|
|
+ return str_has_cntrl(_s);
|
|
+}
|
|
+
|
|
int RGWGetObj_ObjStore_S3::send_response_data(bufferlist& bl, off_t bl_ofs,
|
|
off_t bl_len)
|
|
{
|
|
@@ -271,6 +280,19 @@ int RGWGetObj_ObjStore_S3::send_response_data(bufferlist& bl, off_t bl_ofs,
|
|
if (s->auth.identity->is_anonymous()) {
|
|
return -ERR_INVALID_REQUEST;
|
|
}
|
|
+ /* HTTP specification says no control characters should be present in
|
|
+ * header values: https://tools.ietf.org/html/rfc7230#section-3.2
|
|
+ * field-vchar = VCHAR / obs-text
|
|
+ *
|
|
+ * Failure to validate this permits a CRLF injection in HTTP headers,
|
|
+ * whereas S3 GetObject only permits specific headers.
|
|
+ */
|
|
+ if(str_has_cntrl(val)) {
|
|
+ /* TODO: return a more distinct error in future;
|
|
+ * stating what the problem is */
|
|
+ return -ERR_INVALID_REQUEST;
|
|
+ }
|
|
+
|
|
if (strcmp(p->param, "response-content-type") != 0) {
|
|
response_attrs[p->http_attr] = val;
|
|
} else {
|
|
--
|
|
2.23.0
|
|
|