Esempio n. 1
0
 def generatePolicy(self, reportType):
     """
     Generates a new basic policy that allows exactly the kind of event that caused this CSP violation report,
     assuming the given 'reportType' (permitted values are 'regular', 'eval', and 'inline').
     This assumes that this report contains a specific violated-directive field (it may not be 'default-src').
     If any inconsistent reports are used to generate policies, the policies themselves will be inconsistent. 
     
     Policies should be collected with CSP headers like these:
     
     Content-Security-Policy-Report-Only: default-src 'none'; script-src 'unsafe-eval' 'unsafe-inline'; object-src 'none'; style-src 'unsafe-inline'; img-src 'none'; media-src 'none'; frame-src 'none'; font-src 'none'; connect-src 'none'; report-uri /csp.cgi?type=regular
     Content-Security-Policy-Report-Only: default-src *; script-src * 'unsafe-inline'; style-src * 'unsafe-inline'; report-uri /csp.cgi?type=eval
     Content-Security-Policy-Report-Only: default-src *; script-src * 'unsafe-eval'; style-src *; report-uri /csp.cgi?type=inline
     
     The "type" parameter in the report-uri is equivalent to the 'reportType' parameter of this method.
     
     The results should also be filtered to ensure that only reports sent by fully compatible browsers
     are taken into account. This implementation does not handle URIs in any special way. That is, it does
     not add or remove ports, path/query components, or replace them with the 'self' keyword.
     
     The result is a basic Policy containing one whitelisted resource (corresponding to the violated directive). 
     In practice, it should not be used alone, but be combined with basic policies generated for other violations
     on the same web site. It should also be prepended with "default-src 'none'" to ensure that only the
     whitelisted resources are allowed. (The standard behaviour of CSP in absence of any default Directive is
     to assume "default-src *", which may not be the desired behaviour.)
     
     The result is Policy.INVALID() if (1) the violated directive is missing, Directive.INVALID() or 'default-src', 
     or a special type incompatible with 'reportType', (2) if 'reportType' is none out of 'regular', 'inline' or 'eval', 
     (3) the 'blocked-uri' is URI.INVALID() or not a regular URI in the 'reportType'=='regular' case.
     """
     if (self == Report.INVALID()
         or 'violated-directive' not in self
         or 'blocked-uri' not in self):
         return Policy.INVALID()
     violated = self['violated-directive']
     blocked = self['blocked-uri']
     generated = violated.generateDirective(reportType, blocked)
     if generated == Directive.INVALID():
         return Policy.INVALID()
     else:
         return Policy((generated,))
Esempio n. 2
0
    def parseJsonDict(self, jsonReport):
        """
        Parses the given 'jsonReport' according to the parameters set in the constructor of this ReportParser 
        and returns a Report object. 'jsonReport' is expected to be a Python dict object with attribute names
        and values corresponding to the definition of CSP violation reports. If 'jsonReport' cannot be parsed 
        because it is syntactically invalid (or empty), Report.INVALID() will be returned.

        Depending on the configuration of this ReportParser object, some attributes will be parsed to replace their
        plain string values with a more high-level object representation.
        """
        
        # replace names
        renamedReport = dict(map(lambda (key, val): (self._replaceName(key), val), jsonReport.iteritems()))
                
        # convert data in report
        convertedReport = {}
        deferredSelfURIs = set([]) # all key names that have URIs that are exactly 'self' (handle after parsing everything else)
        for (key, value) in renamedReport.iteritems():
            if key in self._uriKeys:
                if value.lower().strip() == "self":
                    deferredSelfURIs.add(key)
                    continue
                else:
                    value = self._uriParser.parse(value)
            elif key in self._directiveKeys:
                value = self._directiveParser.parse(value)
            elif key in self._policyKeys:
                value = self._policyParser.parse(value)
            
            if value in (URI.INVALID(), Directive.INVALID(), Policy.INVALID()):
                if self._strict:
                    return Report.INVALID()
                else:
                    continue
            convertedReport[key] = value
            
        # handle deferred parsing of 'self' URIs (they represent the document-uri)
        for key in deferredSelfURIs:
            if "document-uri" in self._uriKeys and "document-uri" in convertedReport:
                convertedReport[key] = convertedReport["document-uri"]
            elif self._strict:
                return Report.INVALID()
            
        for requiredKey in self._requiredKeys:
            if not requiredKey in convertedReport:
                return Report.INVALID()
        return Report(convertedReport)