RBAC tightening for share access rule

Non privileged users of unrelated projects
must not be able to retrieve details of an
access rule. We can add a further check to
/share-access-rules APIs to validate that
the caller has access to the share that these
rules pertain to.

Change-Id: I0009a3d682ee5d9a946821c3f82dfd90faa886aa
Closes-Bug: #1917417
Signed-off-by: Goutham Pacha Ravi <gouthampravi@gmail.com>
This commit is contained in:
Goutham Pacha Ravi 2021-03-01 23:05:56 -08:00
parent 8d9fb9250d
commit fc0f669dec
4 changed files with 46 additions and 2 deletions

View File

@ -1987,6 +1987,10 @@ class API(base.Base):
"""Returns access rule with the id.""" """Returns access rule with the id."""
policy.check_policy(context, 'share', 'access_get') policy.check_policy(context, 'share', 'access_get')
rule = self.db.share_access_get(context, access_id) rule = self.db.share_access_get(context, access_id)
# NOTE(gouthamr): Check if the caller has access to the share that
# the rule belongs to:
self.get(context, rule['share_id'])
return rule return rule
@policy.wrap_check_policy('share') @policy.wrap_check_policy('share')

View File

@ -113,6 +113,37 @@ class ShareAccessesAPITest(test.TestCase):
version="2.45") version="2.45")
self.assertRaises(exc.HTTPBadRequest, self.controller.index, req) self.assertRaises(exc.HTTPBadRequest, self.controller.index, req)
def test_show_access_not_authorized(self):
share = db_utils.create_share(
project_id='c3c5ec1ccc4640d0af1914cbf11f05ad',
is_public=False)
access = db_utils.create_access(
id='76699c6b-f3da-47d7-b468-364f1347ba04',
share_id=share['id'])
req = fakes.HTTPRequest.blank(
'/v2/share-access-rules/%s' % access['id'],
version="2.45")
self.mock_object(
policy, 'check_policy',
mock.Mock(side_effect=[None, None, exception.NotAuthorized]))
self.assertRaises(exception.NotAuthorized,
self.controller.show,
req,
access['id'])
policy.check_policy.assert_has_calls([
mock.call(req.environ['manila.context'],
'share_access_rule', 'get'),
mock.call(req.environ['manila.context'],
'share', 'access_get'),
mock.call(req.environ['manila.context'],
'share', 'get', mock.ANY)])
policy_check_call_args_list = policy.check_policy.call_args_list[2][0]
share_being_checked = policy_check_call_args_list[3]
self.assertEqual('c3c5ec1ccc4640d0af1914cbf11f05ad',
share_being_checked['project_id'])
self.assertIs(False, share_being_checked['is_public'])
def test_show_access_not_found(self): def test_show_access_not_found(self):
self.assertRaises( self.assertRaises(
exc.HTTPNotFound, exc.HTTPNotFound,

View File

@ -2695,11 +2695,13 @@ class ShareAPITestCase(test.TestCase):
def test_access_get(self): def test_access_get(self):
with mock.patch.object(db_api, 'share_access_get', with mock.patch.object(db_api, 'share_access_get',
mock.Mock(return_value='fake')): mock.Mock(return_value={'share_id': 'fake'})):
self.mock_object(self.api, 'get')
rule = self.api.access_get(self.context, 'fakeid') rule = self.api.access_get(self.context, 'fakeid')
self.assertEqual('fake', rule) self.assertEqual({'share_id': 'fake'}, rule)
db_api.share_access_get.assert_called_once_with( db_api.share_access_get.assert_called_once_with(
self.context, 'fakeid') self.context, 'fakeid')
self.api.get.assert_called_once_with(self.context, 'fake')
def test_access_get_all(self): def test_access_get_all(self):
share = db_utils.create_share(id='fakeid') share = db_utils.create_share(id='fakeid')

View File

@ -0,0 +1,7 @@
---
security:
- |
An RBAC policy check has been enforced against the GET /share-access-rules
API to ensure that users are permitted to access the share that the
access rule belongs to. See `bug 1917417
<https://launchpad.net/bugs/1917417>`_ for more details.