ceph/0020-CVE-2020-1760-3.patch
chixinze d07f210741 fix CVE-2020-10753 CVE-2021-3524 CVE-2020-1760
Signed-off-by: chixinze <xmdxcxz@gmail.com>
(cherry picked from commit ac0cf1417005186b4542f7e56d6815605e6d2c5c)
2021-08-02 13:54:43 +08:00

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