Deny the non-public method access
Current storlet_handler can allow to access the handler instance method via HTTP verb and it may have a risk to be attacked like brute force. likely: curl http://host/v1/a/c/o -X _parse_vaco -H 'X-Run-Storlet: foo' Fortunately, current handler classes have a few methods inside so that right now probably we don't have any security risk. However, we should strict the method anyway via attatching swift.common.utils.public decorator and the handle_request method should deny the access against to non public method. Change-Id: I22672089950f0d90217a352d82dd60eb1238f9c9
This commit is contained in:
committed by
Takashi Kajinami
parent
b3e9f4fe7e
commit
02292792b1
@@ -22,7 +22,7 @@ from swift.common.swob import HTTPException, Response, \
|
||||
HTTPPreconditionFailed, HTTPRequestedRangeNotSatisfiable, \
|
||||
HTTPInternalServerError, wsgify
|
||||
from swift.common.utils import config_true_value, get_logger, is_success, \
|
||||
register_swift_info
|
||||
register_swift_info, public
|
||||
from swift.common.wsgi import make_subrequest
|
||||
from swift.proxy.controllers.base import get_account_info
|
||||
from storlet_gateway.common.exceptions import StorletRuntimeException, \
|
||||
@@ -361,14 +361,20 @@ class StorletProxyHandler(BaseStorletHandler):
|
||||
|
||||
def handle_request(self):
|
||||
if hasattr(self, self.request.method):
|
||||
resp = getattr(self, self.request.method)()
|
||||
return resp
|
||||
try:
|
||||
handler = getattr(self, self.request.method)
|
||||
getattr(handler, 'publicly_accessible')
|
||||
except AttributeError:
|
||||
# TODO(kota_): add allowed_method list to Allow header
|
||||
return HTTPMethodNotAllowed(request=self.request)
|
||||
return handler()
|
||||
else:
|
||||
raise HTTPMethodNotAllowed(request=self.request)
|
||||
|
||||
def _call_gateway(self, resp):
|
||||
return self.gateway.gatewayProxyGetFlow(self.request, resp)
|
||||
|
||||
@public
|
||||
def GET(self):
|
||||
"""
|
||||
GET handler on Proxy
|
||||
@@ -469,6 +475,7 @@ class StorletProxyHandler(BaseStorletHandler):
|
||||
source_resp.headers['last-modified']
|
||||
return resp
|
||||
|
||||
@public
|
||||
def PUT(self):
|
||||
"""
|
||||
PUT handler on Proxy
|
||||
@@ -489,6 +496,7 @@ class StorletProxyHandler(BaseStorletHandler):
|
||||
self.gateway.gatewayProxyPutFlow(self.request)
|
||||
return self.handle_put_copy_response(out_md, app_iter)
|
||||
|
||||
@public
|
||||
def COPY(self):
|
||||
"""
|
||||
COPY handler on Proxy
|
||||
@@ -541,7 +549,13 @@ class StorletObjectHandler(BaseStorletHandler):
|
||||
|
||||
def handle_request(self):
|
||||
if hasattr(self, self.request.method):
|
||||
return getattr(self, self.request.method)()
|
||||
try:
|
||||
handler = getattr(self, self.request.method)
|
||||
getattr(handler, 'publicly_accessible')
|
||||
except AttributeError:
|
||||
# TODO(kota_): add allowed_method list to Allow header
|
||||
return HTTPMethodNotAllowed(request=self.request)
|
||||
return handler()
|
||||
else:
|
||||
# un-defined method should be NOT ALLOWED
|
||||
raise HTTPMethodNotAllowed(request=self.request)
|
||||
@@ -550,6 +564,7 @@ class StorletObjectHandler(BaseStorletHandler):
|
||||
return self.gateway.gatewayObjectGetFlow(
|
||||
self.request, resp)
|
||||
|
||||
@public
|
||||
def GET(self):
|
||||
"""
|
||||
GET handler on object-server
|
||||
|
||||
@@ -497,6 +497,15 @@ class TestStorletMiddlewareProxy(_TestStorletMiddleware):
|
||||
for key in sheaders:
|
||||
self.assertEqual(resp_headers[key], sheaders[key])
|
||||
|
||||
def test_storlets_with_invalid_method(self):
|
||||
with storlet_enabled():
|
||||
req = Request.blank(
|
||||
'/v1/AUTH_a/c/o', environ={'REQUEST_METHOD': '_parse_vaco'},
|
||||
headers={'X-Run-Storlet': 'Storlet-1.0.jar'})
|
||||
app = self.get_app(self.app, self.conf)
|
||||
app(req.environ, self.start_response)
|
||||
self.assertEqual('405 Method Not Allowed', self.got_statuses[-1])
|
||||
|
||||
|
||||
class TestStorletMiddlewareObject(_TestStorletMiddleware):
|
||||
def setUp(self):
|
||||
@@ -622,6 +631,17 @@ class TestStorletMiddlewareObject(_TestStorletMiddleware):
|
||||
self.assertEqual('200 OK', self.got_statuses[-1])
|
||||
self.assertEqual(resp, ['FAKE SEGMENT'])
|
||||
|
||||
def test_storlets_with_invalid_method(self):
|
||||
target = '/sda1/p/AUTH_a/c/o'
|
||||
|
||||
req = Request.blank(
|
||||
target, environ={'REQUEST_METHOD': '_parse_vaco'},
|
||||
headers={'X-Backend-Storlet-Policy-Index': '0',
|
||||
'X-Run-Storlet': 'Storlet-1.0.jar'})
|
||||
app = self.get_app(self.app, self.conf)
|
||||
app(req.environ, self.start_response)
|
||||
self.assertEqual('405 Method Not Allowed', self.got_statuses[-1])
|
||||
|
||||
|
||||
class TestStorletBaseHandler(unittest.TestCase):
|
||||
def test_init_failed_via_base_handler(self):
|
||||
|
||||
Reference in New Issue
Block a user