/usr/lib/python2.7/dist-packages/swift/common/middleware/name_check.py is in python-swift 2.7.0-0ubuntu2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | # Copyright (c) 2012 OpenStack Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
'''
Created on February 27, 2012
A filter that disallows any paths that contain defined forbidden characters or
that exceed a defined length.
Place early in the proxy-server pipeline after the left-most occurrence of the
``proxy-logging`` middleware (if present) and before the final
``proxy-logging`` middleware (if present) or the ``proxy-serer`` app itself,
e.g.::
[pipeline:main]
pipeline = catch_errors healthcheck proxy-logging name_check cache \
ratelimit tempauth sos proxy-logging proxy-server
[filter:name_check]
use = egg:swift#name_check
forbidden_chars = '"`<>
maximum_length = 255
There are default settings for forbidden_chars (FORBIDDEN_CHARS) and
maximum_length (MAX_LENGTH)
The filter returns HTTPBadRequest if path is invalid.
@author: eamonn-otoole
'''
from six.moves.urllib.parse import unquote
import re
from swift.common.utils import get_logger
from swift.common.swob import Request, HTTPBadRequest
FORBIDDEN_CHARS = "\'\"`<>"
MAX_LENGTH = 255
FORBIDDEN_REGEXP = "/\./|/\.\./|/\.$|/\.\.$"
class NameCheckMiddleware(object):
def __init__(self, app, conf):
self.app = app
self.conf = conf
self.forbidden_chars = self.conf.get('forbidden_chars',
FORBIDDEN_CHARS)
self.maximum_length = int(self.conf.get('maximum_length', MAX_LENGTH))
self.forbidden_regexp = self.conf.get('forbidden_regexp',
FORBIDDEN_REGEXP)
if self.forbidden_regexp:
self.forbidden_regexp_compiled = re.compile(self.forbidden_regexp)
else:
self.forbidden_regexp_compiled = None
self.logger = get_logger(self.conf, log_route='name_check')
def check_character(self, req):
'''
Checks req.path for any forbidden characters
Returns True if there are any forbidden characters
Returns False if there aren't any forbidden characters
'''
self.logger.debug("name_check: path %s" % req.path)
self.logger.debug("name_check: self.forbidden_chars %s" %
self.forbidden_chars)
return any((c in unquote(req.path)) for c in self.forbidden_chars)
def check_length(self, req):
'''
Checks that req.path doesn't exceed the defined maximum length
Returns True if the length exceeds the maximum
Returns False if the length is <= the maximum
'''
length = len(unquote(req.path))
return length > self.maximum_length
def check_regexp(self, req):
'''
Checks that req.path doesn't contain a substring matching regexps.
Returns True if there are any forbidden substring
Returns False if there aren't any forbidden substring
'''
if self.forbidden_regexp_compiled is None:
return False
self.logger.debug("name_check: path %s" % req.path)
self.logger.debug("name_check: self.forbidden_regexp %s" %
self.forbidden_regexp)
unquoted_path = unquote(req.path)
match = self.forbidden_regexp_compiled.search(unquoted_path)
return (match is not None)
def __call__(self, env, start_response):
req = Request(env)
if self.check_character(req):
return HTTPBadRequest(
request=req,
body=("Object/Container/Account name contains forbidden "
"chars from %s"
% self.forbidden_chars))(env, start_response)
elif self.check_length(req):
return HTTPBadRequest(
request=req,
body=("Object/Container/Account name longer than the "
"allowed maximum "
"%s" % self.maximum_length))(env, start_response)
elif self.check_regexp(req):
return HTTPBadRequest(
request=req,
body=("Object/Container/Account name contains a forbidden "
"substring from regular expression %s"
% self.forbidden_regexp))(env, start_response)
else:
# Pass on to downstream WSGI component
return self.app(env, start_response)
def filter_factory(global_conf, **local_conf):
conf = global_conf.copy()
conf.update(local_conf)
def name_check_filter(app):
return NameCheckMiddleware(app, conf)
return name_check_filter
|