Ejemplo n.º 1
0
 def testReport_generatePolicy_fromInvalidDirectiveResult(self):
     reportDefaultSrc = Report({
         "blocked-uri": ReportTest.sampleURI1a,
         "violated-directive": ReportTest.sampleDirective1a,
         "document-uri": ReportTest.sampleURI2
     })
     assert reportDefaultSrc.generatePolicy("regular") == Policy.INVALID()
Ejemplo n.º 2
0
 def testReport_generatePolicy_regular(self):
     report = Report({
         "blocked-uri": ReportTest.sampleURI1a,
         "violated-directive": ReportTest.sampleDirective2a,
         "document-uri": ReportTest.sampleURI2
     })
     assert report.generatePolicy("regular") == Policy(
         [ReportTest.sampleDirective3])
Ejemplo n.º 3
0
 def testReport_generatePolicy_wrongDocumentURI(self):
     reportEmptyDocument = Report({
         "blocked-uri": ReportTest.sampleURI1a,
         "violated-directive": ReportTest.sampleDirective1a,
         "document-uri": URI.EMPTY()
     })
     assert reportEmptyDocument.generatePolicy(
         "regular") == Policy.INVALID()
Ejemplo n.º 4
0
 def testReportParser_parse_requiredFields(self):
     """Required fields must be present even if strict=False."""
     report = """{"this-is": "a quite empty report"}"""
     expected = Report({"this-is": "a quite empty report"})
     assert ReportParser(requiredKeys=[],
                         strict=False).parseString(report) == expected
     assert ReportParser(
         requiredKeys=["does-not-exist"],
         strict=False).parseString(report) == Report.INVALID()
Ejemplo n.º 5
0
 def testReport_generatePolicy_missingReportField(self):
     reportNoViolated = Report({"blocked-uri": ReportTest.sampleURI1a,
                                "document-uri": ReportTest.sampleURI2
                                })
     reportNoBlocked = Report({"violated-directive": ReportTest.sampleDirective2a,
                                "document-uri": ReportTest.sampleURI2
                                })
     assert reportNoViolated.generatePolicy("regular") == Policy.INVALID()
     assert reportNoBlocked.generatePolicy("regular") == Policy.INVALID()
Ejemplo n.º 6
0
 def testReport_dict_iterateAndImmutable(self):
     report = Report({"violated-directive": ReportTest.sampleDirective2a,
                      "original-policy": ReportTest.samplePolicy1a})
     assert len(report) == 2
     assert "violated-directive" in report
     assert report["violated-directive"] == ReportTest.sampleDirective2a
     assert "original-policy" in report
     assert report["original-policy"] == ReportTest.samplePolicy1a
     for (key, value) in report.iteritems():
         assert key in ("violated-directive", "original-policy")
         assert value in (ReportTest.sampleDirective2a, ReportTest.samplePolicy1a)
     with pytest.raises(TypeError):
         report["original-policy"] = None
     with pytest.raises(TypeError):
         report["something-else"] = 123
Ejemplo n.º 7
0
 def testReportParser_parse_unicode(self):
     """The JSON deserialiser returns strings as unicode objects. Check that they are correctly parsed in URIs."""
     fullReport = """{"remote-addr": "XXX", "policy-type": "regular", "http-user-agent":""" \
                 + """ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:27.0) Gecko/20100101 Firefox/27.0",""" \
                 + """ "timestamp-utc": "2014-03-01 12:13:14.156789", "csp-report": {"violated-directive":""" \
                 + """ "img-src 'none'", "referrer": "http://handbook5.com/a/a-security-analysis-of-amazon%E2%80%99s-elastic-compute-cloud-service-w14847.html",""" \
                 + """ "blocked-uri": "http://www.iseclab.org/images/anr.png", "document-uri":""" \
                 + """ "http://www.iseclab.org/?p"}, "header-type": "standard"}"""
     expected = Report({
         "violated-directive":
         Directive("img-src", ()),
         "referrer":
         URI(
             "http", "handbook5.com", None,
             u"/a/a-security-analysis-of-amazon’s-elastic-compute-cloud-service-w14847.html"
         ),
         "blocked-uri":
         URI("http", "www.iseclab.org", None, u"/images/anr.png"),
         "document-uri":
         URI("http", "www.iseclab.org", None, u"/", "p")
     })
     parser = ReportParser(requiredKeys=[])
     jsonReport = json.loads(fullReport)
     cspReport = parser.parseJsonDict(jsonReport["csp-report"])
     assert cspReport == expected
Ejemplo n.º 8
0
 def testReport_str_regular(self):
     """Extended object types should be serialised to strings when getting the report as a string."""
     report = Report({
         "violated-directive": ReportTest.sampleDirective2a,
         "original-policy": ReportTest.samplePolicy1a
     })
     assert str(report) == """{"original-policy": "default-src 'self'; script-src 'unsafe-inline'",""" \
                             + """ "violated-directive": "script-src 'unsafe-inline'"}"""
Ejemplo n.º 9
0
 def testReportParser_parse_selfURIFailStrict(self):
     """Tests that parsing fails if strict and no document-uri but another 'self' URI."""
     report = """{"blocked-uri": "self", "other": "value"}"""
     parser = ReportParser(requiredKeys=[],
                           strict=True,
                           uriKeys=["blocked-uri", "document-uri"])
     cspReport = parser.parseString(report)
     assert cspReport == Report.INVALID()
Ejemplo n.º 10
0
 def testReportParser_parse_selfURISkipStrict(self):
     """Tests that parsing fails if strict and no document-uri but another 'self' URI."""
     report = """{"blocked-uri": "self", "other": "value"}"""
     expected = Report({"other": "value"})
     parser = ReportParser(requiredKeys=[],
                           strict=False,
                           uriKeys=["blocked-uri", "document-uri"])
     cspReport = parser.parseString(report)
     assert cspReport == expected
Ejemplo n.º 11
0
 def testReport_dict_iterateAndImmutable(self):
     report = Report({
         "violated-directive": ReportTest.sampleDirective2a,
         "original-policy": ReportTest.samplePolicy1a
     })
     assert len(report) == 2
     assert "violated-directive" in report
     assert report["violated-directive"] == ReportTest.sampleDirective2a
     assert "original-policy" in report
     assert report["original-policy"] == ReportTest.samplePolicy1a
     for (key, value) in report.iteritems():
         assert key in ("violated-directive", "original-policy")
         assert value in (ReportTest.sampleDirective2a,
                          ReportTest.samplePolicy1a)
     with pytest.raises(TypeError):
         report["original-policy"] = None
     with pytest.raises(TypeError):
         report["something-else"] = 123
Ejemplo n.º 12
0
    def testReport_eq(self):
        report1a = Report({
            "violated-directive": ReportTest.sampleDirective2a,
            "original-policy": ReportTest.samplePolicy1a
        })
        report1b = Report({
            "violated-directive": ReportTest.sampleDirective2b,
            "original-policy": ReportTest.samplePolicy1b
        })
        report2 = Report({
            "violated-directive": ReportTest.sampleDirective1a,
            "original-policy": ReportTest.samplePolicy1a
        })

        assert report1a == report1b
        assert hash(report1a) == hash(report1b)
        assert report1a != report2
        assert report1a != Report.INVALID()
        assert report2 != Report.INVALID()
Ejemplo n.º 13
0
 def testReportParser_parse_emptyOrSelfURI(self):
     """This tests that the internal settings of the URI parser are chosen such that empty or self URIs are
     correctly handled."""
     report = """{"empty-uri": "", "self-uri": "self", "document-uri": "http://seclab.nu"}"""
     expected = Report({
         "empty-uri": URI.EMPTY(),
         "self-uri": ReportTest.sampleURI1a,
         "document-uri": ReportTest.sampleURI1a
     })
     assert ReportParser(requiredKeys=[], strict=True, uriKeys=["empty-uri", "self-uri", "document-uri"]) \
                     .parseString(report) == expected
Ejemplo n.º 14
0
 def testReportParser_parse_stringVsJSON(self):
     """Ensure the string parsing returns the same result as JSON parsing."""
     reportJSON = {"something": 123, "uri": "http://seclab.nu"}
     reportString = """{"something": 123, "uri": "http://seclab.nu"}"""
     expected = Report({"something": 123, "uri": ReportTest.sampleURI1a})
     parser = ReportParser(uriKeys=["uri"], requiredKeys=[], strict=True)
     parsedFromJSON = parser.parseJsonDict(reportJSON)
     parsedFromString = parser.parseString(reportString)
     print parsedFromJSON
     print parsedFromString
     assert parsedFromJSON == parsedFromString
     assert parsedFromJSON == expected
Ejemplo n.º 15
0
 def testReportParser_parse_fieldNameReplacements(self):
     """Checks that old field names are replaced correctly."""
     report = """{"document-url": "http://seclab.nu", "original-policy": "default-src 'self'; script-src 'unsafe-inline'"}"""
     expected = Report({
         "document-uri": ReportTest.sampleURI1a,
         "original-policy": ReportTest.samplePolicy1a
     })
     parser = ReportParser(
         uriKeys=["document-uri"],
         policyKeys=["original-policy"],
         requiredKeys=["document-uri", "original-policy"],
         strict=True,
         keyNameReplacements={"document-url": "document-uri"})
     cspReport = parser.parseString(report)
     assert cspReport == expected
Ejemplo n.º 16
0
 def testReport_generatePolicy_missingReportField(self):
     reportNoViolated = Report({
         "blocked-uri": ReportTest.sampleURI1a,
         "document-uri": ReportTest.sampleURI2
     })
     reportNoBlocked = Report({
         "violated-directive": ReportTest.sampleDirective2a,
         "document-uri": ReportTest.sampleURI2
     })
     assert reportNoViolated.generatePolicy("regular") == Policy.INVALID()
     assert reportNoBlocked.generatePolicy("regular") == Policy.INVALID()
Ejemplo n.º 17
0
    def parseJsonDict(self, jsonLogEntry):
        """
        Parses the given 'jsonLogEntry' according to the parameters set in the constructor of this LogEntryParser 
        and returns a LogEntry object. 'jsonLogEntry' is expected to be a Python dict object. If 'jsonLogEntry' 
        cannot be parsed because it is syntactically invalid (or empty), LogEntry.INVALID() will be returned.
        """

        # TODO: could also parse the timestamp string etc.
        if "csp-report" in jsonLogEntry:
            jsonLogEntry["csp-report"] = self._reportParser.parseJsonDict(
                jsonLogEntry["csp-report"])
            if self._strict and jsonLogEntry["csp-report"] == Report.INVALID():
                return LogEntry.INVALID()
            else:
                return LogEntry(jsonLogEntry)
        else:
            return LogEntry.INVALID()
Ejemplo n.º 18
0
 def testReportParser_parse_typeFields(self):
     """Check that type indications for fields are properly parsed."""
     report = """{"uri": "https://seclab.ccs.neu.edu?query", "directive": "script-src 'unsafe-inline'",""" \
             + """ "policy": "script-src 'unsafe-inline'; default-src 'self'",""" \
             + """ "nothing": "123"}"""
     cspReport = ReportParser(uriKeys=["uri", "url"],
                              directiveKeys=["directive"],
                              policyKeys=["policy"],
                              requiredKeys=[],
                              strict=True).parseString(report)
     expected = Report({
         "uri": ReportTest.sampleURI2,
         "directive": ReportTest.sampleDirective2a,
         "policy": ReportTest.samplePolicy1a,
         "nothing": "123"
     })
     assert cspReport == expected
Ejemplo n.º 19
0
 def testReportCreation(self):
     """Writes a Report and loads it back as an object."""
     report = Report({
         "abc": True,
         "def": 1,
         "ghi": "http://seclab.nu/",
         "document-uri": ReportDataReaderTest.sampleURI1a,
         "violated-directive": ReportDataReaderTest.sampleDirective1a,
         "original-policy": ReportDataReaderTest.samplePolicy1a,
         "blocked-uri": ReportDataReaderTest.sampleURI2
     })
     self.fileOut.storeAll([report])
     self.fileOut.close()
     dataOut = self.fileIn.loadAll(self.filename)
     assert len(dataOut) == 1
     print report
     print dataOut[0]
     assert report in dataOut
Ejemplo n.º 20
0
 def testReportParser_parse_inferSelfURI(self):
     """Tests if the self URI is correctly inferred from the "document-uri" field (even
     after renaming)."""
     report = """{"violated-directive": "default-src 'self'", "referrer": "",""" \
             + """ "blocked-uri": "self", "document-URL":""" \
             + """ "http://seclab.nu"}"""
     expected = Report({
         "violated-directive": ReportTest.sampleDirective1a,
         "referrer": URI.EMPTY(),
         "blocked-uri": ReportTest.sampleURI1a,
         "document-uri": ReportTest.sampleURI1a
     })
     parser = ReportParser(
         requiredKeys=["violated-directive", "document-uri", "blocked-uri"],
         strict=True,
         directiveKeys=["violated-directive"],
         uriKeys=["referrer", "blocked-uri", "document-uri"],
         keyNameReplacements={'document-url': 'document-uri'})
     cspReport = parser.parseString(report)
     assert cspReport == expected
Ejemplo n.º 21
0
 def testReport_generatePolicy_invalid(self):
     assert Report.INVALID().generatePolicy("regular") == Policy.INVALID()
Ejemplo n.º 22
0
 def testReport_generatePolicy_fromInvalidDirectiveResult(self):
     reportDefaultSrc = Report({"blocked-uri": ReportTest.sampleURI1a,
                                "violated-directive": ReportTest.sampleDirective1a,
                                "document-uri": ReportTest.sampleURI2
                                })
     assert reportDefaultSrc.generatePolicy("regular") == Policy.INVALID()
Ejemplo n.º 23
0
 def testReportParser_parse_failIfStrict(self):
     """The report must be declared invalid in strict mode when a child element is invalid."""
     report = """{"invalid-policy": "awesomeness-src 'self'", "example": true}"""
     assert ReportParser(requiredKeys=[], strict=True, policyKeys=["invalid-policy"]) \
                     .parseString(report) == Report.INVALID()
Ejemplo n.º 24
0
 def testReport_generatePolicy_regular(self):
     report = Report({"blocked-uri": ReportTest.sampleURI1a,
                      "violated-directive": ReportTest.sampleDirective2a,
                      "document-uri": ReportTest.sampleURI2
                     })
     assert report.generatePolicy("regular") == Policy([ReportTest.sampleDirective3])
Ejemplo n.º 25
0
 def testReport_generatePolicy_wrongDocumentURI(self):
     reportEmptyDocument = Report({"blocked-uri": ReportTest.sampleURI1a,
                                   "violated-directive": ReportTest.sampleDirective1a,
                                   "document-uri": URI.EMPTY()
                                   })
     assert reportEmptyDocument.generatePolicy("regular") == Policy.INVALID()    
Ejemplo n.º 26
0
 def testReportParser_parse_skipIfNotStrict(self):
     """Invalid portions of the report must be skipped in non-strict mode."""
     report = """{"invalid-policy": "awesomeness-src 'self'", "example": true}"""
     expected = Report({"example": True})
     assert ReportParser(requiredKeys=[], strict=False, policyKeys=["invalid-policy"]) \
                     .parseString(report) == expected
Ejemplo n.º 27
0
class LogEntryTest(unittest.TestCase):

    starSourceExpr = URISourceExpression(None, "*", None, None)
    strLogEntry = """{"csp-report": {"blocked-uri": "", "document-uri": "http://seclab.nu/csp-test.html", """ \
                        + """"original-policy": "default-src *; script-src 'unsafe-eval' *; style-src *", """ \
                        + """"referrer": "", "status-code": 200, "violated-directive": "style-src *"}, """ \
                        + """"header-type": "webkit", "http-user-agent": """ \
                        + """"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, """ \
                        + """like Gecko) Chrome/31.0.1650.63 Safari/537.36", "policy-type": "inline", """ \
                        + """"remote-addr": "1.2.3.4", "timestamp-utc": "2013-12-14 01:02:03.456789"}"""
    logEntryData = {u"csp-report": Report({u"document-uri": URI("http", "seclab.nu", None, u"/csp-test.html"),
                                                  u"referrer": URI.EMPTY(),
                                                  u"violated-directive": Directive("style-src",
                                                                                  (starSourceExpr,)),
                                                  u"original-policy": Policy((Directive("default-src",
                                                                                       (starSourceExpr,)),
                                                                             Directive("script-src",
                                                                                       (starSourceExpr,
                                                                                        SourceExpression.UNSAFE_EVAL())),
                                                                             Directive("style-src",
                                                                                       (starSourceExpr,)))),
                                                  u"blocked-uri": URI.EMPTY(),
                                                  u"status-code": 200
                                                  }),
                            u"remote-addr": u"1.2.3.4",
                            u"http-user-agent": u"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) " \
                                + u"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36",
                            u"timestamp-utc": u"2013-12-14 01:02:03.456789",
                            u"policy-type": u"inline",
                            u"header-type": u"webkit"
                            }
    cspLogEntry = LogEntry(logEntryData)

    def testLogEntry_str_invalid(self):
        assert str(LogEntry.INVALID()) == "[invalid]"

    def testLogEntry_str_regular(self):
        assert str(LogEntryTest.cspLogEntry) == LogEntryTest.strLogEntry

    def testLogEntry_dict_iterateAndImmutable(self):
        assert len(LogEntryTest.cspLogEntry) == 6
        assert "http-user-agent" in LogEntryTest.cspLogEntry
        assert LogEntryTest.cspLogEntry["remote-addr"] == "1.2.3.4"
        for key in LogEntryTest.cspLogEntry.keys():
            assert key in ("csp-report", "remote-addr", "http-user-agent",
                           "timestamp-utc", "policy-type", "header-type")
        with pytest.raises(TypeError):
            LogEntryTest.cspLogEntry["csp-report"] = None
        with pytest.raises(TypeError):
            LogEntryTest.cspLogEntry["something-else"] = 123

    def testLogEntry_eq(self):
        assert LogEntryTest.cspLogEntry != LogEntry.INVALID()

    def testLogEntry_generatePolicy_standard(self):
        assert LogEntryTest.cspLogEntry.generatePolicy() == Policy(
            [Directive("style-src", [SourceExpression.UNSAFE_INLINE()])])

    def testLogEntry_generatePolicy_invalid(self):
        assert LogEntry.INVALID().generatePolicy() == Policy.INVALID()

    def testLogEntry_generatePolicy_incomplete(self):
        logEntryNoReport = LogEntryTest.logEntryData.copy()
        del logEntryNoReport['csp-report']
        logEntryNoPolicyType = LogEntryTest.logEntryData.copy()
        del logEntryNoPolicyType['policy-type']
        assert LogEntry(logEntryNoReport).generatePolicy() == Policy.INVALID()
        assert LogEntry(
            logEntryNoPolicyType).generatePolicy() == Policy.INVALID()

    def testLogEntryParser_parse(self):
        parser = LogEntryParser(strict=True)
        parsed = parser.parseString(LogEntryTest.strLogEntry)
        print parsed._entryData
        print LogEntryTest.cspLogEntry._entryData
        print parsed._entryData[
            'csp-report'] == LogEntryTest.cspLogEntry._entryData['csp-report']
        assert parsed == LogEntryTest.cspLogEntry
Ejemplo n.º 28
0
 def testReport_str_invalid(self):
     assert str(Report.INVALID()) == "[invalid]"
Ejemplo n.º 29
0
 def testReport_str_primitives(self):
     """A Report with basic data types in it (instead of strings) should have them serialised
     to JSON-supported basic data types, not all strings."""
     report = Report({"abc": True, "def": 1, "ghi": ReportTest.sampleURI1a})
     expected = """{"abc": true, "def": 1, "ghi": "http://seclab.nu"}"""
     assert str(report) == expected