]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: anonomous swift to obj that dont exist should 401 33546/head
authorMatthew Oliver <moliver@suse.com>
Wed, 26 Feb 2020 06:15:22 +0000 (06:15 +0000)
committerMatthew Oliver <moliver@suse.com>
Thu, 27 Feb 2020 07:11:08 +0000 (07:11 +0000)
Currently, if you attempt to GET and object in the Swift API that
doesn't exist and you don't pass a `X-Auth-Token` it will 404 instead of
401.

This is actually a rather big problem as it means someone can leak data
out of the cluster, not object data itself, but if an object exists or
not.

This is caused by the SwiftAnonymousEngine's, frankly wide open
is_applicable acceptance. When we get to checking the bucket or object
for user acceptance we  deal with it properly, but if the object doesn't
exsit, because the user has been "authorised" rgw returns a 404.

Why? Because we always override the user with the Swift account.
Meaning as far as checks are concerned the auth user is the user, not
and anonymous user.

I assume this is because a swift container could have world readable
reads or writes and in slight s3 and swift api divergents can make these
interesting edge cases leak in.

This patch doesn't change the user to the swift account if they are
anonymous. So we can do some anonymous checks when it suits later in the
request processing path.

Fixes: https://tracker.ceph.com/issues/43617
Signed-off-by: Matthew Oliver <moliver@suse.com>
src/rgw/rgw_auth.h
src/rgw/rgw_op.cc
src/rgw/rgw_swift_auth.h

index 38f51b790a8f88c0cb388732d86b4e4a4718704d..a08a7f3024e2a20f27e07b5e386646c956590c78 100644 (file)
@@ -491,6 +491,7 @@ public:
       is_admin(acct_privilege_t::IS_ADMIN_ACCT == level),
       acct_type(acct_type) {
     }
+    bool is_anon() const {return (acct_name.compare(RGW_USER_ANON_ID) == 0);}
   };
 
   using aclspec_t = rgw::auth::Identity::aclspec_t;
index cb8e8a90d5333e71f6c476ebeb2085d04164f34d..27cac54a8c5f06e2c37bc3cd84d59d3ae3e7892b 100644 (file)
@@ -7621,6 +7621,8 @@ int RGWHandler::do_read_permissions(RGWOp *op, bool only_bucket)
                      << " ret=" << ret << dendl;
     if (ret == -ENODATA)
       ret = -EACCES;
+    if (s->auth.identity->is_anonymous() && ret == -EACCES)
+      ret = -EPERM;
   }
 
   return ret;
index 6270ee67599563a330599ceb45eee1b57acaa92f..8cefbf1a4880da8e4707e68cb4d1964b4e7b66bd 100644 (file)
@@ -4,6 +4,8 @@
 #ifndef CEPH_RGW_SWIFT_AUTH_H
 #define CEPH_RGW_SWIFT_AUTH_H
 
+#include "rgw_common.h"
+#include "rgw_user.h"
 #include "rgw_op.h"
 #include "rgw_rest.h"
 #include "rgw_auth.h"
@@ -142,6 +144,16 @@ public:
   }
 };
 
+/* SwiftAnonymous: applier. */
+class SwiftAnonymousApplier : public rgw::auth::LocalApplier {
+  public:
+    SwiftAnonymousApplier(CephContext* const cct,
+                          const RGWUserInfo& user_info)
+      : LocalApplier(cct, user_info, LocalApplier::NO_SUBUSER, boost::none) {
+      };
+    bool is_admin_of(const rgw_user& uid) const {return false;}
+    bool is_owner_of(const rgw_user& uid) const {return false;}
+};
 
 class SwiftAnonymousEngine : public rgw::auth::AnonymousEngine {
   const rgw::auth::TokenExtractor* const extractor;
@@ -152,7 +164,7 @@ class SwiftAnonymousEngine : public rgw::auth::AnonymousEngine {
 
 public:
   SwiftAnonymousEngine(CephContext* const cct,
-                       const rgw::auth::LocalApplier::Factory* const apl_factory,
+                       const SwiftAnonymousApplier::Factory* const apl_factory,
                        const rgw::auth::TokenExtractor* const extractor)
     : AnonymousEngine(cct, apl_factory),
       extractor(extractor) {
@@ -195,8 +207,11 @@ class DefaultStrategy : public rgw::auth::Strategy,
                              const req_state* const s,
                              acl_strategy_t&& extra_acl_strategy,
                              const rgw::auth::RemoteApplier::AuthInfo &info) const override {
+    rgw_user user(s->account_name);
+    if (info.is_anon())
+      user = rgw_user(RGW_USER_ANON_ID);
     auto apl = \
-      rgw::auth::add_3rdparty(ctl, rgw_user(s->account_name),
+      rgw::auth::add_3rdparty(ctl, user,
         rgw::auth::add_sysreq(cct, ctl, s,
           rgw::auth::RemoteApplier(cct, ctl, std::move(extra_acl_strategy), info,
                                    implicit_tenant_context,
@@ -210,8 +225,11 @@ class DefaultStrategy : public rgw::auth::Strategy,
                             const RGWUserInfo& user_info,
                             const std::string& subuser,
                             const boost::optional<uint32_t>& perm_mask) const override {
+    rgw_user user(s->account_name);
+    if (user_info.user_id.compare(RGW_USER_ANON_ID) == 0)
+      user = rgw_user(user_info.user_id);
     auto apl = \
-      rgw::auth::add_3rdparty(ctl, rgw_user(s->account_name),
+      rgw::auth::add_3rdparty(ctl, user,
         rgw::auth::add_sysreq(cct, ctl, s,
           rgw::auth::LocalApplier(cct, user_info, subuser, perm_mask)));
     /* TODO(rzarzynski): replace with static_ptr. */