def __call__(self, info, request): # Support running under the same instance for local devleopment and for # test.pypi.io which will continue to host it's own uploader. if self.val is None: return True return is_same_domain(request.domain, self.val)
def check_csrf_origin(request, trusted_origins=None, raises=True): """ Check the ``Origin`` of the request to see if it is a cross site request or not. If the value supplied by the ``Origin`` or ``Referer`` header isn't one of the trusted origins and ``raises`` is ``True``, this function will raise a :exc:`pyramid.exceptions.BadCSRFOrigin` exception, but if ``raises`` is ``False``, this function will return ``False`` instead. If the CSRF origin checks are successful this function will return ``True`` unconditionally. Additional trusted origins may be added by passing a list of domain (and ports if non-standard like ``['example.com', 'dev.example.com:8080']``) in with the ``trusted_origins`` parameter. If ``trusted_origins`` is ``None`` (the default) this list of additional domains will be pulled from the ``pyramid.csrf_trusted_origins`` setting. Note that this function will do nothing if ``request.scheme`` is not ``https``. .. versionadded:: 1.7 .. versionchanged:: 1.9 Moved from :mod:`pyramid.session` to :mod:`pyramid.csrf` """ def _fail(reason): if raises: raise BadCSRFOrigin(reason) else: return False if request.scheme == "https": # Suppose user visits http://example.com/ # An active network attacker (man-in-the-middle, MITM) sends a # POST form that targets https://example.com/detonate-bomb/ and # submits it via JavaScript. # # The attacker will need to provide a CSRF cookie and token, but # that's no problem for a MITM when we cannot make any assumptions # about what kind of session storage is being used. So the MITM can # circumvent the CSRF protection. This is true for any HTTP connection, # but anyone using HTTPS expects better! For this reason, for # https://example.com/ we need additional protection that treats # http://example.com/ as completely untrusted. Under HTTPS, # Barth et al. found that the Referer header is missing for # same-domain requests in only about 0.2% of cases or less, so # we can use strict Referer checking. # Determine the origin of this request origin = request.headers.get("Origin") if origin is None: origin = request.referrer # Fail if we were not able to locate an origin at all if not origin: return _fail("Origin checking failed - no Origin or Referer.") # Parse our origin so we we can extract the required information from # it. originp = urlparse(origin) # Ensure that our Referer is also secure. if originp.scheme != "https": return _fail( "Referer checking failed - Referer is insecure while host is " "secure.") # Determine which origins we trust, which by default will include the # current origin. if trusted_origins is None: trusted_origins = aslist( request.registry.settings.get("pyramid.csrf_trusted_origins", [])) if request.host_port not in set(["80", "443"]): trusted_origins.append("{0.domain}:{0.host_port}".format(request)) else: trusted_origins.append(request.domain) # Actually check to see if the request's origin matches any of our # trusted origins. if not any( is_same_domain(originp.netloc, host) for host in trusted_origins): reason = ( "Referer checking failed - {0} does not match any trusted " "origins.") return _fail(reason.format(origin)) return True
def _callFUT(self, *args, **kw): from pyramid.util import is_same_domain return is_same_domain(*args, **kw)
def check_csrf_origin(request, trusted_origins=None, raises=True): """ Check the Origin of the request to see if it is a cross site request or not. If the value supplied by the Origin or Referer header isn't one of the trusted origins and ``raises`` is ``True``, this function will raise a :exc:`pyramid.exceptions.BadCSRFOrigin` exception but if ``raises`` is ``False`` this function will return ``False`` instead. If the CSRF origin checks are successful this function will return ``True`` unconditionally. Additional trusted origins may be added by passing a list of domain (and ports if nonstandard like `['example.com', 'dev.example.com:8080']`) in with the ``trusted_origins`` parameter. If ``trusted_origins`` is ``None`` (the default) this list of additional domains will be pulled from the ``pyramid.csrf_trusted_origins`` setting. Note that this function will do nothing if request.scheme is not https. .. versionadded:: 1.7 """ def _fail(reason): if raises: raise BadCSRFOrigin(reason) else: return False if request.scheme == "https": # Suppose user visits http://example.com/ # An active network attacker (man-in-the-middle, MITM) sends a # POST form that targets https://example.com/detonate-bomb/ and # submits it via JavaScript. # # The attacker will need to provide a CSRF cookie and token, but # that's no problem for a MITM when we cannot make any assumptions # about what kind of session storage is being used. So the MITM can # circumvent the CSRF protection. This is true for any HTTP connection, # but anyone using HTTPS expects better! For this reason, for # https://example.com/ we need additional protection that treats # http://example.com/ as completely untrusted. Under HTTPS, # Barth et al. found that the Referer header is missing for # same-domain requests in only about 0.2% of cases or less, so # we can use strict Referer checking. # Determine the origin of this request origin = request.headers.get("Origin") if origin is None: origin = request.referrer # Fail if we were not able to locate an origin at all if not origin: return _fail("Origin checking failed - no Origin or Referer.") # Parse our origin so we we can extract the required information from # it. originp = urlparse.urlparse(origin) # Ensure that our Referer is also secure. if originp.scheme != "https": return _fail( "Referer checking failed - Referer is insecure while host is " "secure." ) # Determine which origins we trust, which by default will include the # current origin. if trusted_origins is None: trusted_origins = aslist( request.registry.settings.get( "pyramid.csrf_trusted_origins", []) ) if request.host_port not in set(["80", "443"]): trusted_origins.append("{0.domain}:{0.host_port}".format(request)) else: trusted_origins.append(request.domain) # Actually check to see if the request's origin matches any of our # trusted origins. if not any(is_same_domain(originp.netloc, host) for host in trusted_origins): reason = ( "Referer checking failed - {0} does not match any trusted " "origins." ) return _fail(reason.format(origin)) return True