def __init__(self, includeSelf=False, enabled=True, reportViolations=False, useForwardedHeader=False): """Create a new :api:`twisted.web.resource.Resource` which adds a ``'Content-Security-Policy:'`` header. If enabled, the default Content Security Policy is:: default-src 'none' ; base-uri FQDN ; script-src FQDN ; style-src FQDN ; img-src FQDN data: ; font-src FQDN ; where ``FQDN`` the value returned from the :func:`getFQDN` function (which uses the ``SERVER_PUBLIC_FQDN`` config file option). If the **includeSelf** parameter is enabled, then ``"'self'"`` (literally, a string containing the word ``self``, surrounded by single-quotes) will be appended to the ``FQDN``. :param str fqdn: The public, fully-qualified domain name of the HTTP server that will serve this resource. :param bool includeSelf: Append ``'self'`` after the **fqdn** in the Content Security Policy. :param bool enabled: If ``False``, all Content Security Policy headers, including those used in report-only mode, will not be sent. If ``True``, Content Security Policy headers (regardless of whether report-only mode is dis-/en-abled) will be sent. (default: ``True``) :param bool reportViolations: Use the Content Security Policy in report-only mode, causing CSP violations to be reported back to the server (at :attr:`reportURI`, where the details of the violation will be logged). (default: ``False``) :param bool useForwardedHeader: If ``True``, then we will attempt to obtain the client's IP address from the ``X-Forwarded-For`` HTTP header. This *only* has an effect if **reportViolations** is also set to ``True`` — the client's IP address is logged along with any CSP violation reports which the client sent via HTTP POST requests to our :attr:`reportURI`. (default: ``False``) """ resource.Resource.__init__(self) self.fqdn = getFQDN() self.enabled = enabled self.useForwardedHeader = useForwardedHeader self.csp = ("default-src 'none'; " "base-uri {0}; " "script-src {0}; " "style-src {0}; " "img-src {0} data:; " "font-src {0}; ") if includeSelf: self.fqdn = " ".join([self.fqdn, "'self'"]) if reportViolations: self.reportViolations = reportViolations
def getFQDNAndRoot(): """Get the server's public FQDN plus the root directory for the web server. """ root = getRoot() fqdn = getFQDN() if not root.startswith('/') and not fqdn.endswith('/'): return '/'.join([fqdn, root]) else: return ''.join([fqdn, root])
def setCSPHeader(self, request): """Set the CSP header for a **request**. If this :class:`CSPResource` is :attr:`enabled`, then use :api:`twisted.web.http.Request.setHeader` to send an HTTP ``'Content-Security-Policy:'`` header for any response made to the **request** (or a ``'Content-Security-Policy-Report-Only:'`` header, if :attr:`reportViolations` is enabled). :type request: :api:`twisted.web.http.Request` :param request: A ``Request`` object for :attr:`reportViolationURI`. """ self.fqdn = self.fqdn or getFQDN() # Update the FQDN if it changed. if self.enabled and self.fqdn: if not self.reportViolations: request.setHeader("Content-Security-Policy", self.csp.format(self.fqdn)) else: logging.debug("Sending report-only CSP header...") request.setHeader("Content-Security-Policy-Report-Only", self.csp.format(self.fqdn) + "report-uri /%s" % self.reportURI)
def setCSPHeader(self, request): """Set the CSP header for a **request**. If this :class:`CSPResource` is :attr:`enabled`, then use :api:`twisted.web.http.Request.setHeader` to send an HTTP ``'Content-Security-Policy:'`` header for any response made to the **request** (or a ``'Content-Security-Policy-Report-Only:'`` header, if :attr:`reportViolations` is enabled). :type request: :api:`twisted.web.http.Request` :param request: A ``Request`` object for :attr:`reportViolationURI`. """ self.fqdn = self.fqdn or getFQDN() # Update the FQDN if it changed. if self.enabled and self.fqdn: if not self.reportViolations: request.setHeader("Content-Security-Policy", self.csp.format(self.fqdn)) else: logging.debug("Sending report-only CSP header...") request.setHeader( "Content-Security-Policy-Report-Only", self.csp.format(self.fqdn) + "report-uri /%s" % self.reportURI)