]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: Set Access-Control-Allow-Origin to a Asterisk if allowed in a rule 8528/head
authorWido den Hollander <wido@42on.com>
Tue, 5 Apr 2016 09:14:16 +0000 (11:14 +0200)
committerWido den Hollander <wido@42on.com>
Sun, 3 Jul 2016 09:10:55 +0000 (11:10 +0200)
Before this patch the RGW would respond with the Origin send by the client in the request
if a wildcard/asterisk was specified as a valid Origin.

This patch makes sure we respond with a header like this:

  Access-Control-Allow-Origin: *

This way a resource can be used on different Origins by the same browser and that browser
will use the content as the asterisk.

We also keep in mind that when Authorization is send by the client different rules apply.
In the case of Authorization we may not respond with an Asterisk, but we do have to
add the Vary header with 'Origin' as a value to let the browser know that for different
Origins it has to perform a new request.

More information: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

Fixes: #15348
Signed-off-by: Wido den Hollander <wido@42on.com>
(cherry picked from commit 0021e224480c7164330eaa7cc1078bb8795169bf)

Conflicts:
src/rgw/rgw_rest.cc
hammer still uses s->cio->print() where master uses STREAM_IO(s)->print()

src/rgw/rgw_cors.cc
src/rgw/rgw_cors.h
src/rgw/rgw_op.cc
src/rgw/rgw_rest.cc

index a120a6866455e505dbe312406877d5840c18f2d8..1ad5b43136cf351c459070d07bdb618c37941e33 100644 (file)
@@ -116,6 +116,13 @@ static bool is_string_in_set(set<string>& s, string h) {
   return false;
 }
 
+bool RGWCORSRule::has_wildcard_origin() {
+  if (allowed_origins.find("*") != allowed_origins.end())
+    return true;
+
+  return false;
+}
+
 bool RGWCORSRule::is_origin_present(const char *o) {
   string origin = o;
   return is_string_in_set(allowed_origins, origin);
index 124ebf92a7f23dfafcfda4fa076784068dbdda43..c5877ea5836aad4dca52452becd6ec8db2fc3771 100644 (file)
@@ -81,6 +81,7 @@ public:
     ::decode(exposable_hdrs, bl);
     DECODE_FINISH(bl);
   }
+  bool has_wildcard_origin();
   bool is_origin_present(const char *o);
   void format_exp_headers(std::string& s);
   void erase_origin_if_present(std::string& origin, bool *rule_empty);
index d81ae32e1f2a167a73348e2e9624b0421f5a0451..663ec614f8abc91363b69af872763c22312d6723 100644 (file)
@@ -634,6 +634,18 @@ bool RGWOp::generate_cors_headers(string& origin, string& method, string& header
   if (!rule)
     return false;
 
+  /*
+   * Set the Allowed-Origin header to a asterisk if this is allowed in the rule
+   * and no Authorization was send by the client
+   *
+   * The origin parameter specifies a URI that may access the resource.  The browser must enforce this.
+   * For requests without credentials, the server may specify "*" as a wildcard,
+   * thereby allowing any origin to access the resource.
+   */
+  const char *authorization = s->info.env->get("HTTP_AUTHORIZATION");
+  if (!authorization && rule->has_wildcard_origin())
+    origin = "*";
+
   /* CORS 6.2.3. */
   const char *req_meth = s->info.env->get("HTTP_ACCESS_CONTROL_REQUEST_METHOD");
   if (!req_meth) {
index 859e34a770b6e09ea4cdb9fce236e669c34daeb2..f5fe69341f0954e9b2996d88488db177b7fbe01e 100644 (file)
@@ -459,6 +459,15 @@ void dump_access_control(struct req_state *s, const char *origin, const char *me
                          const char *hdr, const char *exp_hdr, uint32_t max_age) {
   if (origin && (origin[0] != '\0')) {
     s->cio->print("Access-Control-Allow-Origin: %s\r\n", origin);
+
+    /* If the server specifies an origin host rather than "*",
+     * then it must also include Origin in the Vary response header
+     * to indicate to clients that server responses will differ
+     * based on the value of the Origin request header.
+     */
+    if (strcmp(origin, "*") != 0)
+      s->cio->print("Vary: Origin\r\n");
+
     if (meth && (meth[0] != '\0'))
       s->cio->print("Access-Control-Allow-Methods: %s\r\n", meth);
     if (hdr && (hdr[0] != '\0'))