This file is indexed.

/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