cubicweb/web/cors.py
author Denis Laxalde <denis.laxalde@logilab.fr>
Fri, 05 Apr 2019 17:58:19 +0200
changeset 12567 26744ad37953
parent 11348 70337ad23145
permissions -rw-r--r--
Drop python2 support This mostly consists in removing the dependency on "six" and updating the code to use only Python3 idioms. Notice that we previously used TemporaryDirectory from cubicweb.devtools.testlib for compatibility with Python2. We now directly import it from tempfile.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
     1
# copyright 2014-2016 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
     2
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
     3
#
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
     4
# This file is part of CubicWeb.
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
     5
#
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
     6
# CubicWeb is free software: you can redistribute it and/or modify it under the
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
     7
# terms of the GNU Lesser General Public License as published by the Free
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
     8
# Software Foundation, either version 2.1 of the License, or (at your option)
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
     9
# any later version.
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
    10
#
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
    11
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
    12
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
    13
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
    14
# details.
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
    15
#
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
    16
# You should have received a copy of the GNU Lesser General Public License along
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
9571
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    18
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    19
"""A set of utility functions to handle CORS requests
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    20
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    21
Unless specified, all references in this file are related to:
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    22
  http://www.w3.org/TR/cors
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    23
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    24
The provided implementation roughly follows:
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    25
  http://www.html5rocks.com/static/images/cors_server_flowchart.png
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    26
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    27
See also:
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    28
  https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    29
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    30
"""
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    31
12567
26744ad37953 Drop python2 support
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11348
diff changeset
    32
from urllib.parse import urlsplit
9571
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    33
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    34
from cubicweb.web import LOGGER
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    35
info = LOGGER.info
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    36
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    37
class CORSFailed(Exception):
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    38
    """Raised when cross origin resource sharing checks failed"""
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    39
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    40
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    41
class CORSPreflight(Exception):
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    42
    """Raised when cross origin resource sharing checks detects the
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    43
    request as a valid preflight request"""
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    44
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    45
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    46
def process_request(req, config):
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    47
    """
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    48
    Process a request to apply CORS specification algorithms
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    49
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    50
    Check whether the CORS specification is respected and set corresponding
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    51
    headers to ensure response complies with the specification.
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    52
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    53
    In case of non-compliance, no CORS-related header is set.
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    54
    """
10603
65ad6980976e [py3k] import URL mangling functions using six.moves
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10588
diff changeset
    55
    base_url = urlsplit(req.base_url())
9571
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    56
    expected_host = '://'.join((base_url.scheme, base_url.netloc))
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    57
    if not req.get_header('Origin') or req.get_header('Origin') == expected_host:
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    58
        # not a CORS request, nothing to do
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    59
        return
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    60
    try:
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    61
        # handle cross origin resource sharing (CORS)
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    62
        if req.http_method() == 'OPTIONS':
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    63
            if req.get_header('Access-Control-Request-Method'):
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    64
                # preflight CORS request
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    65
                process_preflight(req, config)
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    66
        else: # Simple CORS or actual request
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    67
            process_simple(req, config)
10588
fdaa0e4b7eaf [py3k] except as
Samuel Trégouët <samuel.tregouet@logilab.fr>
parents: 10002
diff changeset
    68
    except CORSFailed as exc:
9571
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    69
        info('Cross origin resource sharing failed: %s' % exc)
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    70
    except CORSPreflight:
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    71
        info('Cross origin resource sharing: valid Preflight request %s')
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    72
        raise
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    73
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    74
def process_preflight(req, config):
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    75
    """cross origin resource sharing (preflight)
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    76
    Cf http://www.w3.org/TR/cors/#resource-preflight-requests
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    77
    """
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    78
    origin = check_origin(req, config)
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    79
    allowed_methods = set(config['access-control-allow-methods'])
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    80
    allowed_headers = set(config['access-control-allow-headers'])
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    81
    try:
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    82
        method = req.get_header('Access-Control-Request-Method')
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    83
    except ValueError:
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    84
        raise CORSFailed('Access-Control-Request-Method is incorrect')
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    85
    if method not in allowed_methods:
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    86
        raise CORSFailed('Method is not allowed')
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    87
    try:
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    88
        req.get_header('Access-Control-Request-Headers', ())
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    89
    except ValueError:
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    90
        raise CORSFailed('Access-Control-Request-Headers is incorrect')
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    91
    req.set_header('Access-Control-Allow-Methods', allowed_methods, raw=False)
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    92
    req.set_header('Access-Control-Allow-Headers', allowed_headers, raw=False)
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    93
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    94
    process_common(req, config, origin)
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    95
    raise CORSPreflight()
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    96
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    97
def process_simple(req, config):
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    98
    """Handle the Simple Cross-Origin Request case
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    99
    """
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   100
    origin = check_origin(req, config)
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   101
    exposed_headers = config['access-control-expose-headers']
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   102
    if exposed_headers:
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   103
        req.set_header('Access-Control-Expose-Headers', exposed_headers, raw=False)
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   104
    process_common(req, config, origin)
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   105
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   106
def process_common(req, config, origin):
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   107
    req.set_header('Access-Control-Allow-Origin', origin)
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   108
    # in CW, we always support credential/authentication
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   109
    req.set_header('Access-Control-Allow-Credentials', 'true')
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   110
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   111
def check_origin(req, config):
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   112
    origin = req.get_header('Origin').lower()
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   113
    allowed_origins = config.get('access-control-allow-origin')
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   114
    if not allowed_origins:
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   115
        raise CORSFailed('access-control-allow-origin is not configured')
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   116
    if '*' not in allowed_origins and origin not in allowed_origins:
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   117
        raise CORSFailed('Origin is not allowed')
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   118
    # bit of sanity check; see "6.3 Security"
10603
65ad6980976e [py3k] import URL mangling functions using six.moves
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10588
diff changeset
   119
    myhost = urlsplit(req.base_url()).netloc
9571
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   120
    host = req.get_header('Host')
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   121
    if host != myhost:
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   122
        info('cross origin resource sharing detected possible '
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   123
             'DNS rebinding attack Host header != host of base_url: '
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   124
             '%s != %s' % (host, myhost))
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   125
        raise CORSFailed('Host header and hostname do not match')
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   126
    # include "Vary: Origin" header (see 6.4)
10002
586d0e527052 [web/cors] don't overwrite other Vary headers
Julien Cristau <julien.cristau@logilab.fr>
parents: 9571
diff changeset
   127
    req.headers_out.addHeader('Vary', 'Origin')
9571
aaf83cc07eed [web] implement cross origin resource sharing (CORS) (closes #2491768)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   128
    return origin