Exemplo n.º 1
0
 def test_SelfSourceExpression_match(self):
     """A 'self' source expression matches if the scheme, host and port of the self and other URI
     are the same (using default ports if absent)."""
     selfURI = URI("http", "seclab.nu", 80, "/other-path")
     srcExpr = SelfSourceExpression.SELF()
     assert srcExpr.matches(SourceExpressionTest.uri_urlFull, selfURI)
     assert srcExpr.matches(SourceExpressionTest.uri_urlFull_longer1,
                            selfURI)
     assert not srcExpr.matches(SourceExpressionTest.uri_urlFull_secure,
                                selfURI)
     assert not srcExpr.matches(SourceExpressionTest.uri_url1Sub, selfURI)
     assert srcExpr.matches(SourceExpressionTest.uri_schemedomain,
                            selfURI)  # using default port in URI
     assert not srcExpr.matches(URI.EMPTY(), selfURI)
     assert not srcExpr.matches(URI.INVALID(), selfURI)
     assert not srcExpr.matches(URI.INLINE(), selfURI)
     assert not srcExpr.matches(URI.EVAL(), selfURI)
     selfURIDefaultPort = URI("https", "seclab.nu", None,
                              "/yet-another-path")
     assert not srcExpr.matches(SourceExpressionTest.uri_urlFull_secure,
                                selfURIDefaultPort)
     assert srcExpr.matches(
         SourceExpressionTest.uri_urlFull_secure_defaultPort,
         selfURIDefaultPort)
     selfURINoPort = SourceExpressionTest.uri_chromeExtension
     assert not srcExpr.matches(
         SourceExpressionTest.uri_chromeExtension,
         selfURINoPort)  # no valid port can be deduced from this scheme
Exemplo n.º 2
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
Exemplo n.º 3
0
 def test_URISourceExpression_match_query(self):
     """The query component in an URI should not matter when matching."""
     srcExpr = URISourceExpression("http", "seclab.nu", 80, "/path")
     selfURI = SourceExpressionTest.uri_urlFull_secure
     assert srcExpr.matches(URI("http", "seclab.nu", 80, "/path", None),
                            selfURI)
     assert srcExpr.matches(URI("http", "seclab.nu", 80, "/path", "query"),
                            selfURI)
Exemplo n.º 4
0
 def test_URISourceExpression_match_empty_path(self):
     """If the path component of the source expression or the URI is the empty string, it
     should be treated the same as being None."""
     srcExprEmpty = URISourceExpression("http", "seclab.nu", 80, "")
     srcExprNone = URISourceExpression("http", "seclab.nu", 80, None)
     selfURI = SourceExpressionTest.uri_urlFull_secure
     assert srcExprEmpty.matches(SourceExpressionTest.uri_urlFull, selfURI)
     assert srcExprEmpty.matches(URI("http", "seclab.nu", 80, ""), selfURI)
     assert srcExprEmpty.matches(URI("http", "seclab.nu", 80, None),
                                 selfURI)
     assert srcExprNone.matches(SourceExpressionTest.uri_urlFull, selfURI)
     assert srcExprNone.matches(URI("http", "seclab.nu", 80, ""), selfURI)
     assert srcExprNone.matches(URI("http", "seclab.nu", 80, None), selfURI)
Exemplo n.º 5
0
 def test_str(self):
     """Checks the string serialisation of a few URIs."""
     assert str(URI("data", "", None, None)) == "data:"
     assert str(URI("data", "image/png;base64,iVBORw0KGgoAAAA", None,
                    None)) == "data:image/png;base64,iVBORw0KGgoAAAA"
     assert str(URI("about", "blank", None, None)) == "about:blank"
     assert str(
         URI("http", "www.seclab.org", 80, "/file", "parameter=value")
     ) == "http://www.seclab.org:80/file?parameter=value"
     assert str(URI(None, "www.seclab.nu", None, None)) == "www.seclab.nu"
     assert str(URI.EMPTY()) == ""
     assert str(URI.INVALID()) == "[invalid]"
     assert str(URI.INLINE()) == "[inline]"
     assert str(URI.EVAL()) == "[eval]"
Exemplo n.º 6
0
 def test_no_modification_partial_URI_scheme_host(self):
     """Simple test with no modification, splitting a partially specified URI."""
     uriString = "chrome-extension://mkfokfffehpeedafpekjeddnmnjhmcmk"
     uriExpected = URI("chrome-extension",
                       "mkfokfffehpeedafpekjeddnmnjhmcmk", None, None)
     assert URIParser(addScheme=False, addPort=False, decodeEscapedCharacters=False) \
             .parse(uriString) == uriExpected
Exemplo n.º 7
0
 def test_addPort_schemePortMappingsNone_partial_URI_scheme_host(self):
     """Simple test with "adding" a None port, splitting a partially specified URI."""
     uriString = "chrome-extension://mkfokfffehpeedafpekjeddnmnjhmcmk"
     uriExpected = URI("chrome-extension",
                       "mkfokfffehpeedafpekjeddnmnjhmcmk", None, None)
     assert URIParser(addScheme=True, addPort=True, defaultPort=123, schemePortMappings={'chrome-extension': None}, decodeEscapedCharacters=False) \
         .parse(uriString) == uriExpected
Exemplo n.º 8
0
 def test_str_unicode(self):
     """Test URI serialisation with unicode characters."""
     url = u'http://handbook5.com/a/a-security-analysis-of-amazon%E2%80%99s-elastic-compute-cloud-service-w14847.html'
     unicodePath = u"/a/a-security-analysis-of-amazon’s-elastic-compute-cloud-service-w14847.html"
     parsed = URIParser(decodeEscapedCharacters=True).parse(url)
     assert parsed == URI("http", "handbook5.com", None, unicodePath)
     assert str(parsed) == url  # must use quoted version
Exemplo n.º 9
0
 def test_addScheme_addPort_defaultScheme_schemePortMappings_partial_URI_host_path(
         self):
     """Test if scheme and port are added properly to partially specified URI."""
     uriString = "www.seclab.nu/path/file"
     uriExpected = URI("test-scheme", "www.seclab.nu", 333, "/path/file")
     assert URIParser(addScheme=True, defaultScheme="test-scheme", addPort=True, schemePortMappings={"test-scheme": 333}, decodeEscapedCharacters=False) \
         .parse(uriString) == uriExpected
Exemplo n.º 10
0
 def test_no_modification_partial_URI_data(self):
     """Data URIs use only the scheme and the host for the data. The data should not be converted to
     lowercase."""
     uriString = "data:image/png;base64,iVBORw0KGgoAAAA"
     uriExpected = URI("data", "image/png;base64,iVBORw0KGgoAAAA", None,
                       None)
     assert URIParser().parse(uriString) == uriExpected
Exemplo n.º 11
0
 def test_no_modification_partial_URI_host_path(self):
     """Simple test with no modification, splitting a partially specified URI."""
     uriString = "www.seclab.nu/path/file"
     uriExpected = URI(None, "www.seclab.nu", None, "/path/file")
     actual = URIParser(addScheme=False, addPort=False, decodeEscapedCharacters=False) \
         .parse(uriString)
     assert actual == uriExpected
Exemplo n.º 12
0
 def test_stripUserPassword_userOnly_URI_IPv4(self):
     """Check if user:password part properly removed (with IPv4 address)."""
     uriString = "http://[email protected]:80/index.php"
     uriExpected = URI("http", "123.123.123.123", 80, "/index.php")
     actual = URIParser(decodeEscapedCharacters=False) \
         .parse(uriString)
     assert actual == uriExpected
Exemplo n.º 13
0
 def test_stripUserPassword_userOnly_URI(self):
     """Check if user:password part properly removed."""
     uriString = "http://[email protected]:80/index.php"
     uriExpected = URI("http", "www.seclab.nu", 80, "/index.php")
     actual = URIParser(decodeEscapedCharacters=False) \
         .parse(uriString)
     assert actual == uriExpected
Exemplo n.º 14
0
 def test_no_modification_partial_URI_scheme_host_path_query(self):
     """Simple test with no modification, splitting a partially specified URI."""
     uriString = "https://www.seclab.nu/path/file?query=here"
     uriExpected = URI("https", "www.seclab.nu", None, "/path/file",
                       "query=here")
     assert URIParser(addScheme=False, addPort=False, decodeEscapedCharacters=False) \
         .parse(uriString) == uriExpected
Exemplo n.º 15
0
 def testPolicy_matches_matchingDirectiveType(self):
     """Policy contains directive of resource type that matches."""
     pol = Policy(
         (PolicyTest.sampleDirective1a, PolicyTest.sampleDirective5))
     selfURI = PolicyTest.sampleURI2
     assert pol.matches(
         URI("https", "abc.seclab.nu", 443, "/path", "some-query"),
         "connect-src", selfURI)
Exemplo n.º 16
0
 def test_regularURI_singletons(self):
     """All the singleton URIs should return False for isRegularURI()."""
     assert URI.EMPTY().isRegularURI() == False
     assert URI.INVALID().isRegularURI() == False
     assert URI.INLINE().isRegularURI() == False
     assert URI.EVAL().isRegularURI() == False
     assert URI("http", "seclab.nu", None, None,
                None).isRegularURI() == True
Exemplo n.º 17
0
 def test_decodeEscapedCharacters_full_URI(self):
     """Check if escaped characters in the path are correctly decoded."""
     uriString = "http://www.seclab.nu:80/a%20path/index.py?math=3%3D%281%2B1%29%2A1.5"
     uriExpected = URI("http", "www.seclab.nu", 80, "/a path/index.py",
                       "math=3%3D%281%2B1%29%2A1.5")
     actual = URIParser(decodeEscapedCharacters=True) \
         .parse(uriString)
     assert actual == uriExpected
Exemplo n.º 18
0
 def test_stripAnchor_full_URI(self):
     """Check if anchor part properly removed."""
     uriString = "http://www.seclab.nu:80/index.php?parameter=value&more#anchor"
     uriExpected = URI("http", "www.seclab.nu", 80, "/index.php",
                       "parameter=value&more")
     actual = URIParser(decodeEscapedCharacters=False) \
         .parse(uriString)
     assert actual == uriExpected
Exemplo n.º 19
0
class ReportDataReaderTest(unittest.TestCase):

    sampleURI1a = URI("http", "seclab.nu", None, None, None)
    sampleURI1b = URI("http", "seclab.nu", None, None, None)
    sampleURI2 = URI("http", "seclab.nu", None, "/blocked", "query")
    sampleDirective1a = Directive("default-src", ())
    sampleDirective1b = Directive("default-src", ())
    sampleDirective2a = Directive("script-src",
                                  (SourceExpression.UNSAFE_INLINE(), ))
    sampleDirective2b = Directive("script-src",
                                  (SourceExpression.UNSAFE_INLINE(), ))
    samplePolicy1a = Policy((sampleDirective1a, sampleDirective2a))
    samplePolicy1b = Policy((sampleDirective1b, sampleDirective2b))
    samplePolicy2 = Policy((sampleDirective1a, ))

    @pytest.fixture(autouse=True)
    def initdir(self, tmpdir):
        tmpdir.chdir()

    def setUp(self):
        self.fileIn = ReportDataReader(True)
        self.filename = "encodingdecoding.dat"
        self.fileOut = DataWriter(self.filename)

    def tearDown(self):
        pass

    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
Exemplo n.º 20
0
 def test_getters(self):
     """Checks the getters of URI."""
     inputURI = URI("https", "seclab.nu", 443, "/index.html", "param=val")
     assert inputURI.getScheme() == "https"
     assert inputURI.getHost() == "seclab.nu"
     assert inputURI.getPort() == 443
     assert inputURI.getPath() == "/index.html"
     assert inputURI.getQuery() == "param=val"
     assert inputURI.isRegularURI() == True
Exemplo n.º 21
0
 def test_eq(self):
     """Checks that the eq and hash methods are consistent for a few URIs."""
     uri1a = URI("http", "www.seclab.org", 80, "/", "query")
     uri1b = URI("http", "www.seclab.org", 80, "/", "query")
     uri2 = URI("https", "www.seclab.org", 80, "/")
     uri3 = URI("http", "www.seclab.org", 80, None)
     assert uri1a == uri1b
     assert hash(uri1a) == hash(uri1b)
     assert uri1a != uri2
     assert uri1a != uri3
     assert uri2 != uri3
     assert URI.EMPTY() == URI.EMPTY()
     assert URI.INVALID() == URI.INVALID()
     assert URI.EMPTY() not in (uri1a, uri1b, uri2, uri3, URI.INVALID(),
                                URI.INLINE(), URI.EVAL())
     assert URI.INVALID() not in (uri1a, uri1b, uri2, uri3, URI.EMPTY(),
                                  URI.INLINE(), URI.EVAL())
     assert URI.INLINE() not in (uri1a, uri1b, uri2, uri3, URI.EMPTY(),
                                 URI.INVALID(), URI.EVAL())
     assert URI.EVAL() not in (uri1a, uri1b, uri2, uri3, URI.EMPTY(),
                               URI.INVALID(), URI.INLINE())
Exemplo n.º 22
0
 def test_no_modification_partial_URI_host(self):
     """Simple test with no modification and only host in URI."""
     uriString = "www.seclab.nu"
     uriExpected = URI(None, "www.seclab.nu", None, None)
     assert URIParser(addScheme=False,
                      addPort=False).parse(uriString) == uriExpected
Exemplo n.º 23
0
class ReportTest(unittest.TestCase):

    sampleURI1a = URI("http", "seclab.nu", None, None, None)
    sampleURI1b = URI("http", "seclab.nu", None, None, None)
    sampleURI2 = URI("https", "seclab.ccs.neu.edu", None, None, "query")
    sampleDirective1a = Directive("default-src",
                                  (SelfSourceExpression.SELF(), ))
    sampleDirective1b = Directive("default-src", (SelfSourceExpression(), ))
    sampleDirective2a = Directive("script-src",
                                  (SourceExpression.UNSAFE_INLINE(), ))
    sampleDirective2b = Directive("script-src",
                                  (SourceExpression.UNSAFE_INLINE(), ))
    sampleDirective3 = Directive(
        "script-src", (URISourceExpression("http", "seclab.nu", None, None), ))
    samplePolicy1a = Policy((sampleDirective1a, sampleDirective2a))
    samplePolicy1b = Policy((sampleDirective1b, sampleDirective2b))

    def testReport_str_invalid(self):
        assert str(Report.INVALID()) == "[invalid]"

    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'"}"""

    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

    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

    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()

    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])

    def testReport_generatePolicy_invalid(self):
        assert Report.INVALID().generatePolicy("regular") == Policy.INVALID()

    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()

    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()

    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()

    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

    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

    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

    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()

    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

    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()

    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

    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

    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()

    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

    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
Exemplo n.º 24
0
class DirectiveTest(unittest.TestCase):

    sampleURI1 = URI("http", "seclab.nu", 80, None, None)
    sampleURI2 = URI("http", "seclab.ccs.neu.edu", 80, "/path",
                     "query-parameters")
    sampleSrcExpr1a = URISourceExpression("http", "seclab.nu", "*", None)
    sampleSrcExpr1b = URISourceExpression("http", "seclab.nu", "*", None)
    sampleSrcExpr2 = URISourceExpression("https", "seclab.nu", 443, "/path1")
    sampleSrcExpr3 = URISourceExpression("https", "seclab.nu", 443, "/path2")

    def testDirective_str_none(self):
        assert str(Directive("script-src", [])) == "script-src 'none'"

    def testDirective_str_regular(self):
        srcExpr1 = URISourceExpression("http", "seclab.nu", "*", None)
        srcExpr2 = SourceExpression.UNSAFE_INLINE()
        srcExpr3 = SelfSourceExpression.SELF()
        assert str(Directive("style-src", [srcExpr1, srcExpr2, srcExpr3])) \
            == "style-src 'self' 'unsafe-inline' http://seclab.nu:*"

    def testDirective_str_invalid(self):
        assert str(Directive.INVALID()) == "[invalid]"

    def testDirective_str_inlineStyleBaseRestriction(self):
        assert str(Directive.INLINE_STYLE_BASE_RESTRICTION()
                   ) == "inline style base restriction"

    def testDirective_str_inlineScriptBaseRestriction(self):
        assert str(Directive.INLINE_SCRIPT_BASE_RESTRICTION()
                   ) == "inline script base restriction"

    def testDirective_str_evalScriptBaseRestriction(self):
        assert str(Directive.EVAL_SCRIPT_BASE_RESTRICTION()
                   ) == "eval script base restriction"

    def testDirective_getType(self):
        assert Directive("default-src", []).getType() == "default-src"
        assert Directive.INLINE_STYLE_BASE_RESTRICTION().getType(
        ) == "style-src"
        assert Directive.INLINE_SCRIPT_BASE_RESTRICTION().getType(
        ) == "script-src"
        assert Directive.EVAL_SCRIPT_BASE_RESTRICTION().getType(
        ) == "script-src"

    def testDirective_init_removeDoubleExpressions(self):
        srcExpr1 = URISourceExpression("http", "seclab.nu", "*", None)
        srcExpr2 = URISourceExpression("http", "seclab.nu", "*", None)
        directive = Directive("style-src", [srcExpr1, srcExpr2])
        whitelisted = directive.getWhitelistedSourceExpressions()
        assert whitelisted == set(
            [srcExpr1])  # duplicate source expressions should be removed
        assert whitelisted == set([srcExpr2])  # sets should be equal
        assert directive == Directive("style-src", [srcExpr1])
        assert directive == Directive("style-src", [srcExpr2])

    def testDirective_init_removeDoubleSelfExpressions(self):
        srcExpr1 = URISourceExpression("http", "seclab.nu", "*", None)
        srcExpr2 = SelfSourceExpression.SELF()
        srcExpr3 = SelfSourceExpression()
        whitelisted = Directive(
            "img-src",
            [srcExpr1, srcExpr2, srcExpr3]).getWhitelistedSourceExpressions()
        assert len(
            whitelisted
        ) == 2  # one self expression should be removed (can have at most one)
        assert srcExpr1 in whitelisted and (srcExpr2 in whitelisted
                                            or srcExpr3 in whitelisted)

    def testDirective_init_removeInvalidSourceExpressions(self):
        assert Directive("img-src", [SourceExpression.INVALID()]) == Directive(
            "img-src", [])

    def testDirective_eq(self):
        srcExpr1 = URISourceExpression("http", "seclab.nu", "*", None)
        srcExpr2 = URISourceExpression("https", "seclab.nu", 443, "/")
        directive1a = Directive("object-src", [srcExpr1, srcExpr2])
        directive1b = Directive("object-src", [srcExpr2, srcExpr1])
        directive2 = Directive("frame-src", [srcExpr1, srcExpr2])
        directive3 = Directive("object-src", [srcExpr2])
        directive4a = Directive("script-src",
                                (SourceExpression.UNSAFE_INLINE(), ))
        directive4b = Directive("script-src",
                                (SourceExpression("unsafe-inline"), ))
        assert directive1a == directive1b
        assert hash(directive1a) == hash(directive1b)
        assert directive1a != directive2
        assert directive1a != directive3
        assert directive2 != directive3
        assert directive4a == directive4b
        assert hash(directive4a) == hash(directive4b)
        assert Directive.INVALID() == Directive.INVALID()
        assert Directive.INVALID() not in (directive1a, directive1b,
                                           directive2, directive3)
        assert Directive.INLINE_STYLE_BASE_RESTRICTION() not in (directive1a,
                                                                 directive1b,
                                                                 directive2,
                                                                 directive3)

    def testDirective_matches_special(self):
        """An invalid/special directive matches nothing."""
        selfURI = DirectiveTest.sampleURI2
        assert not Directive.INVALID().matches(URI.EMPTY(), selfURI)
        assert not Directive.INVALID().matches(URI.INVALID(), selfURI)
        assert not Directive.INVALID().matches(URI.INLINE(), selfURI)
        assert not Directive.INVALID().matches(URI.EVAL(), selfURI)
        assert not Directive.INVALID().matches(DirectiveTest.sampleURI1,
                                               selfURI)
        assert not Directive.EVAL_SCRIPT_BASE_RESTRICTION().matches(
            URI.EMPTY(), selfURI)
        assert not Directive.EVAL_SCRIPT_BASE_RESTRICTION().matches(
            URI.INVALID(), selfURI)
        assert not Directive.EVAL_SCRIPT_BASE_RESTRICTION().matches(
            URI.INLINE(), selfURI)
        assert not Directive.EVAL_SCRIPT_BASE_RESTRICTION().matches(
            URI.EVAL(), selfURI)
        assert not Directive.EVAL_SCRIPT_BASE_RESTRICTION().matches(
            DirectiveTest.sampleURI1, selfURI)
        assert not Directive.INLINE_SCRIPT_BASE_RESTRICTION().matches(
            URI.EMPTY(), selfURI)
        assert not Directive.INLINE_SCRIPT_BASE_RESTRICTION().matches(
            URI.INVALID(), selfURI)
        assert not Directive.INLINE_SCRIPT_BASE_RESTRICTION().matches(
            URI.INLINE(), selfURI)
        assert not Directive.INLINE_SCRIPT_BASE_RESTRICTION().matches(
            URI.EVAL(), selfURI)
        assert not Directive.INLINE_SCRIPT_BASE_RESTRICTION().matches(
            DirectiveTest.sampleURI1, selfURI)
        assert not Directive.INLINE_STYLE_BASE_RESTRICTION().matches(
            URI.EMPTY(), selfURI)
        assert not Directive.INLINE_STYLE_BASE_RESTRICTION().matches(
            URI.INVALID(), selfURI)
        assert not Directive.INLINE_STYLE_BASE_RESTRICTION().matches(
            URI.INLINE(), selfURI)
        assert not Directive.INLINE_STYLE_BASE_RESTRICTION().matches(
            URI.EVAL(), selfURI)
        assert not Directive.INLINE_STYLE_BASE_RESTRICTION().matches(
            DirectiveTest.sampleURI1, selfURI)

    def testDirective_matches(self):
        """A few standard tests."""
        directive1 = Directive(
            "object-src",
            [DirectiveTest.sampleSrcExpr1a, DirectiveTest.sampleSrcExpr2])
        directive2 = Directive("frame-src", [DirectiveTest.sampleSrcExpr2])
        directive3 = Directive("default-src", [])
        selfURI = DirectiveTest.sampleURI2
        assert directive1.matches(DirectiveTest.sampleURI1, selfURI)
        assert not directive1.matches(DirectiveTest.sampleURI2, selfURI)
        assert not directive2.matches(DirectiveTest.sampleURI1, selfURI)
        assert not directive2.matches(DirectiveTest.sampleURI2, selfURI)
        assert not directive3.matches(DirectiveTest.sampleURI1, selfURI)
        assert not directive3.matches(DirectiveTest.sampleURI2, selfURI)

    def testDirective_generateDirective_regular(self):
        violated = Directive(
            "object-src",
            [DirectiveTest.sampleSrcExpr1a, DirectiveTest.sampleSrcExpr2])
        generated = violated.generateDirective("regular",
                                               DirectiveTest.sampleURI2)
        assert generated == Directive(
            "object-src",
            [URISourceExpression("http", "seclab.ccs.neu.edu", 80, "/path")])

    def testDirective_generateDirective_inline(self):
        violated = Directive("style-src", [DirectiveTest.sampleSrcExpr2])
        generated = violated.generateDirective("inline", URI.EMPTY())
        assert generated == Directive("style-src",
                                      [SourceExpression.UNSAFE_INLINE()])

    def testDirective_generateDirective_inline_special_style(self):
        violated = Directive.INLINE_STYLE_BASE_RESTRICTION()
        generated = violated.generateDirective("inline",
                                               DirectiveTest.sampleURI1)
        assert generated == Directive("style-src",
                                      [SourceExpression.UNSAFE_INLINE()])

    def testDirective_generateDirective_inline_special_script(self):
        violated = Directive.INLINE_SCRIPT_BASE_RESTRICTION()
        generated = violated.generateDirective("inline",
                                               DirectiveTest.sampleURI1)
        assert generated == Directive("script-src",
                                      [SourceExpression.UNSAFE_INLINE()])

    def testDirective_generateDirective_eval(self):
        violated = Directive("script-src", [DirectiveTest.sampleSrcExpr1a])
        generated = violated.generateDirective("eval", URI.EMPTY())
        assert generated == Directive("script-src",
                                      [SourceExpression.UNSAFE_EVAL()])

    def testDirective_generateDirective_eval_special(self):
        violated = Directive.EVAL_SCRIPT_BASE_RESTRICTION()
        generated = violated.generateDirective("eval",
                                               DirectiveTest.sampleURI2)
        assert generated == Directive("script-src",
                                      [SourceExpression.UNSAFE_EVAL()])

    def testDirective_generateDirective_invalidType(self):
        violated = Directive("script-src", [DirectiveTest.sampleSrcExpr1a])
        assert violated.generateDirective("evaluate",
                                          URI.EMPTY()) == Directive.INVALID()

    def testDirective_generateDirective_invalidDirective(self):
        assert Directive.INVALID().generateDirective(
            "eval", URI.EMPTY()) == Directive.INVALID()

    def testDirective_generateDirective_defaultSrcNotAllowed(self):
        violated = Directive("default-src", [])
        assert violated.generateDirective(
            "regular", DirectiveTest.sampleURI1) == Directive.INVALID()

    def testDirective_generateDirective_incompatibleType(self):
        violatedWrongInlineType = Directive("object-src", [])
        violatedWrongEvalType = Directive("style-src", [])
        assert violatedWrongInlineType.generateDirective(
            "inline", DirectiveTest.sampleURI1) == Directive.INVALID()
        assert violatedWrongEvalType.generateDirective(
            "eval", DirectiveTest.sampleURI1) == Directive.INVALID()

    def testDirective_generateDirective_incompatibleURI(self):
        violatedRegular = Directive("object-src", [])
        violatedInline = Directive("style-src", [])
        violatedEval = Directive("script-src", [])
        assert violatedRegular.generateDirective(
            "regular", URI.EMPTY()) == Directive.INVALID()
        assert violatedRegular.generateDirective(
            "regular", URI.INVALID()) == Directive.INVALID()
        #assert violatedInline.generateDirective("inline", DirectiveTest.sampleURI1) == Directive.INVALID()
        assert violatedInline.generateDirective(
            "inline", URI.INVALID()) == Directive.INVALID()
        #assert violatedEval.generateDirective("eval", DirectiveTest.sampleURI1) == Directive.INVALID()
        assert violatedEval.generateDirective(
            "eval", URI.INVALID()) == Directive.INVALID()

    def testDirective_isRegularDirective(self):
        assert Directive.INVALID().isRegularDirective() == False
        assert Directive.EVAL_SCRIPT_BASE_RESTRICTION().isRegularDirective(
        ) == False
        assert Directive.INLINE_SCRIPT_BASE_RESTRICTION().isRegularDirective(
        ) == False
        assert Directive.INLINE_STYLE_BASE_RESTRICTION().isRegularDirective(
        ) == False
        assert Directive("default-src", []).isRegularDirective() == True

    def testDirective_combine_regular(self):
        direct1 = Directive("default-src", [DirectiveTest.sampleSrcExpr1a])
        direct2 = Directive("default-src", [DirectiveTest.sampleSrcExpr2])
        expected = Directive(
            "default-src",
            [DirectiveTest.sampleSrcExpr1a, DirectiveTest.sampleSrcExpr2])
        assert direct1.combinedDirective(direct2) == expected
        assert direct2.combinedDirective(direct1) == expected
        assert direct1.combinedDirective(direct1) == direct1
        assert direct2.combinedDirective(direct2) == direct2

    def testDirective_combine_differentType(self):
        direct1 = Directive("default-src", [DirectiveTest.sampleSrcExpr1a])
        direct2 = Directive("script-src", [DirectiveTest.sampleSrcExpr2])
        assert direct1.combinedDirective(direct2) == Directive.INVALID()
        assert direct2.combinedDirective(direct1) == Directive.INVALID()

    def testDirective_combine_notRegularURI(self):
        direct = Directive("style-src", [SelfSourceExpression.SELF()])
        assert direct.combinedDirective(
            Directive.INVALID()) == Directive.INVALID()
        assert Directive.INVALID().combinedDirective(
            direct) == Directive.INVALID()
        assert direct.combinedDirective(
            Directive.EVAL_SCRIPT_BASE_RESTRICTION()) == Directive.INVALID()
        assert Directive.EVAL_SCRIPT_BASE_RESTRICTION().combinedDirective(
            direct) == Directive.INVALID()

    def testDirective_combine_removeDuplicates(self):
        direct1 = Directive(
            "img-src",
            [DirectiveTest.sampleSrcExpr1a,
             SelfSourceExpression.SELF()])
        direct2 = Directive("img-src", [DirectiveTest.sampleSrcExpr1b])
        assert direct1.combinedDirective(direct2) == direct1
        assert direct2.combinedDirective(direct1) == direct1

    def testDirective_withoutPaths(self):
        withPaths = Directive(
            "script-src",
            [DirectiveTest.sampleSrcExpr2,
             SelfSourceExpression.SELF()])
        withoutPaths = Directive("script-src", [
            DirectiveTest.sampleSrcExpr2.removePath(),
            SelfSourceExpression.SELF()
        ])
        assert withPaths.withoutPaths() == withoutPaths
        assert withoutPaths.withoutPaths() == withoutPaths
        assert Directive.INVALID().withoutPaths() == Directive.INVALID()
        assert Directive.EVAL_SCRIPT_BASE_RESTRICTION().withoutPaths(
        ) == Directive.EVAL_SCRIPT_BASE_RESTRICTION()
        assert Directive.INLINE_SCRIPT_BASE_RESTRICTION().withoutPaths(
        ) == Directive.INLINE_SCRIPT_BASE_RESTRICTION()
        assert Directive.INLINE_STYLE_BASE_RESTRICTION().withoutPaths(
        ) == Directive.INLINE_STYLE_BASE_RESTRICTION()

    def testDirective_withoutPaths_schemeOnly(self):
        chromeExt = Directive("img-src", [
            URISourceExpression("chrome-extension",
                                "mkfokfffehpeedafpekjeddnmnjhmcmk", None, None)
        ])
        assert chromeExt.withoutPaths(["chrome-extension"]) == Directive(
            "img-src",
            [URISourceExpression("chrome-extension", None, None, None)])

    def testDirective_withoutPaths_removeDuplicates(self):
        withPaths = Directive(
            "script-src",
            [DirectiveTest.sampleSrcExpr2, DirectiveTest.sampleSrcExpr3])
        withoutPaths = Directive("script-src",
                                 [DirectiveTest.sampleSrcExpr2.removePath()])
        assert withPaths.withoutPaths() == withoutPaths

    def testDirective_asBasicDirectives_single(self):
        assert Directive.INVALID().asBasicDirectives() == set([])
        assert Directive.EVAL_SCRIPT_BASE_RESTRICTION().asBasicDirectives(
        ) == set([])
        assert Directive.INLINE_SCRIPT_BASE_RESTRICTION().asBasicDirectives(
        ) == set([])
        assert Directive.INLINE_STYLE_BASE_RESTRICTION().asBasicDirectives(
        ) == set([])
        sampleDirective = Directive("img-src", [DirectiveTest.sampleSrcExpr1b])
        assert sampleDirective.asBasicDirectives() == set([sampleDirective])

    def testDirective_asBasicDirectives_multiple(self):
        sampleDirective = Directive("script-src", [
            SelfSourceExpression.SELF(), DirectiveTest.sampleSrcExpr1a,
            DirectiveTest.sampleSrcExpr2, DirectiveTest.sampleSrcExpr3
        ])
        assert sampleDirective.asBasicDirectives() == set([
            Directive("script-src", [SelfSourceExpression.SELF()]),
            Directive("script-src", [DirectiveTest.sampleSrcExpr1a]),
            Directive("script-src", [DirectiveTest.sampleSrcExpr2]),
            Directive("script-src", [DirectiveTest.sampleSrcExpr3])
        ])

    def testDirective_isBasicDirective(self):
        assert Directive.INVALID().isBasicDirective() == False
        assert Directive.EVAL_SCRIPT_BASE_RESTRICTION().isBasicDirective(
        ) == False
        assert Directive("default-src", ()).isBasicDirective() == True
        assert Directive(
            "script-src",
            [DirectiveTest.sampleSrcExpr2]).isBasicDirective() == True
        assert Directive(
            "object-src",
            [DirectiveTest.sampleSrcExpr2, DirectiveTest.sampleSrcExpr3
             ]).isBasicDirective() == False

    def testDirectiveParser_parse_empty(self):
        assert DirectiveParser(strict=True).parse("  ") == Directive.INVALID()
        assert DirectiveParser(strict=False).parse("  ") == Directive.INVALID()
        assert DirectiveParser(
            strict=True).parse("img-src ") == Directive.INVALID()
        assert DirectiveParser(
            strict=False).parse("img-src ") == Directive.INVALID()

    def testDirectiveParser_parse_standard(self):
        assert DirectiveParser(strict=True).parse("default-src https: 'unsafe-inline' 'unsafe-eval'") \
            == Directive("default-src", [URISourceExpression("https", None, None, None),
                                         SourceExpression.UNSAFE_INLINE(), SourceExpression.UNSAFE_EVAL()])
        assert DirectiveParser(strict=True).parse("default-src 'self'") \
            == Directive("default-src", [SelfSourceExpression.SELF()])
        assert DirectiveParser(strict=True).parse("img-src *") \
            == Directive("img-src", [URISourceExpression(None, "*", None, None)])
        assert DirectiveParser(strict=True).parse("object-src media1.example.com media2.example.com *.cdn.example.com") \
            == Directive("object-src", [URISourceExpression(None, "media1.example.com", None, None),
                                        URISourceExpression(None, "media2.example.com", None, None),
                                        URISourceExpression(None, "*.cdn.example.com", None, None)])

    def testDirectiveParser_parse_whitespaceRemoval(self):
        """Whitespace is properly removed."""
        directive = "img-src  'self'  https://abc.cloudfront.net/the-path chrome-extension: data: https://def.cloudfront.net/another-path "
        directiveClean = "img-src 'self' chrome-extension: data: https://abc.cloudfront.net/the-path https://def.cloudfront.net/another-path"
        cspDirective = DirectiveParser().parse(directive)
        assert cspDirective.getType() == "img-src"
        assert cspDirective.getWhitelistedSourceExpressions() == set([
            SelfSourceExpression.SELF(),
            URISourceExpression("chrome-extension", None, None, None),
            URISourceExpression("data", None, None, None),
            URISourceExpression("https", "abc.cloudfront.net", None,
                                "/the-path"),
            URISourceExpression("https", "def.cloudfront.net", None,
                                "/another-path")
        ])
        assert str(cspDirective) == directiveClean
        cspDirectiveClean = DirectiveParser().parse(directiveClean)
        assert cspDirective == cspDirectiveClean

    def testDirectiveParser_parse_invalid(self):
        invalidDirective = "blah"
        assert DirectiveParser().parse(invalidDirective) is Directive.INVALID()

    def testDirectiveParser_parse_translate(self):
        """The old directive type 'xhr-src' is correctly rewritten to 'connect-src'."""
        translateDirective = "xhr-src http://localhost"
        cspTranslateDirective = DirectiveParser().parse(translateDirective)
        assert cspTranslateDirective == Directive(
            "connect-src",
            (URISourceExpression("http", "localhost", None, None), ))

    def testDirectiveParser_parse_ignore(self):
        """Report URIs are not supported in CSP Directives."""
        ignoredDirective = "report-uri http://localhost/saveme.exe"
        assert DirectiveParser().parse(ignoredDirective) is Directive.INVALID()

    def testDirectiveParser_parse_none(self):
        """Parse a 'none' value."""
        noneDirective = """default-src 'none' """
        cspNoneDirective = DirectiveParser().parse(noneDirective)
        assert cspNoneDirective == Directive("default-src", [])

    def testDirectiveParser_parse_none_syntaxerror_strict(self):
        """If 'none' appears in a directive parsed strictly, no other values are permitted."""
        noneDirectiveInvalid = """default-src http://one 'None' http://two"""
        assert DirectiveParser(strict=True).parse(noneDirectiveInvalid) \
            == Directive.INVALID()

    def testDirectiveParser_parse_none_syntaxerror_notstrict(self):
        """If 'none' appears in a directive not parsed strictly and other expressions occur, 'none' is ignored."""
        noneDirectiveInvalid = """default-src http://one 'None' http://two"""
        cspDirective = DirectiveParser(
            strict=False).parse(noneDirectiveInvalid)
        assert cspDirective == Directive("default-src", [
            URISourceExpression("http", "one", None, None),
            URISourceExpression("http", "two", None, None)
        ])

    def testDirectiveParser_parse_invalidSourceExpression_strict(self):
        """In strict mode, only valid source expressions may be used."""
        invalidDirective = """img-src http://url 'blah'"""
        assert DirectiveParser(strict=True).parse(invalidDirective) \
            == Directive.INVALID()

    def testDirectiveParser_parse_invalidSourceExpression_notstrict(self):
        """In non-strict mode, invalid source expressions are ignored."""
        invalidDirective = """img-src http://url 'blah'"""
        cspDirective = DirectiveParser(strict=False).parse(invalidDirective)
        assert cspDirective == Directive(
            "img-src", [URISourceExpression("http", "url", None, None)])

    def testDirectiveParser_parse_inline(self):
        """'unsafe-inline' keyword allowed only in 'script-src' and 'style-src' and 'default-src'"""
        scriptSrcWithInline = """script-src 'self' 'unsafe-inline' http://me.com/"""
        styleSrcWithInline = """style-src 'unsafe-inline' http://other"""
        styleSrcWithInlineOnly = """style-src 'unsafe-inline'"""
        defaultSrcWithInlineOnly = """default-src 'unsafe-inline'"""
        invalidObjectSrcWithInline = """object-src 'self' 'unsafe-inline'"""
        invalidObjectSrcWithInlineOnly = """object-src 'unsafe-inline'"""
        assert str(DirectiveParser().parse(
            scriptSrcWithInline)) == scriptSrcWithInline
        assert str(
            DirectiveParser().parse(styleSrcWithInline)) == styleSrcWithInline
        assert str(DirectiveParser().parse(
            styleSrcWithInlineOnly)) == styleSrcWithInlineOnly
        assert str(DirectiveParser().parse(
            defaultSrcWithInlineOnly)) == defaultSrcWithInlineOnly
        assert DirectiveParser(strict=True).parse(invalidObjectSrcWithInline) \
            == Directive.INVALID()
        assert str(DirectiveParser(strict=False).parse(invalidObjectSrcWithInline)) \
            == "object-src 'self'"
        assert DirectiveParser(strict=True).parse(invalidObjectSrcWithInlineOnly) \
            == Directive.INVALID()
        assert str(DirectiveParser(strict=False).parse(invalidObjectSrcWithInlineOnly)) \
            == "object-src 'none'"

    def testDirectiveParser_parse_eval(self):
        """'unsafe-eval' keyword allowed only in 'script-src' and 'default-src'"""
        scriptSrcWithEval = """script-src 'self' 'unsafe-eval' 'unsafe-inline'"""
        scriptSrcWithEvalOnly = """script-src 'unsafe-eval'"""
        defaultSrcWithInlineAndEvalOnly = """default-src 'unsafe-eval' 'unsafe-inline'"""
        invalidImgSrcWithEval = """img-src http://example/path 'unsafe-eval'"""
        assert str(
            DirectiveParser().parse(scriptSrcWithEval)) == scriptSrcWithEval
        assert str(DirectiveParser().parse(
            scriptSrcWithEvalOnly)) == scriptSrcWithEvalOnly
        assert str(DirectiveParser().parse(defaultSrcWithInlineAndEvalOnly)) \
            == defaultSrcWithInlineAndEvalOnly
        assert DirectiveParser(strict=True).parse(invalidImgSrcWithEval) \
            == Directive.INVALID()
        assert str(DirectiveParser(strict=False).parse(invalidImgSrcWithEval)) \
            == "img-src http://example/path"

    def testDirectiveParser_parse_inlineStyleBaseRestriction(self):
        """The Firefox value 'inline style base restriction' for the 'violated-directive' field is parsed
        correctly."""
        firefoxViolatedDirective = "inline style base restriction"
        assert DirectiveParser().parse(firefoxViolatedDirective) \
                == Directive.INLINE_STYLE_BASE_RESTRICTION()

    def testDirectiveParser_parse_inlineScriptBaseRestriction(self):
        """The Firefox value 'inline script base restriction' for the 'violated-directive' field is parsed
        correctly."""
        firefoxViolatedDirective = "inline script base restriction"
        assert DirectiveParser().parse(firefoxViolatedDirective) \
                == Directive.INLINE_SCRIPT_BASE_RESTRICTION()

    def testDirectiveParser_parse_evalScriptBaseRestriction(self):
        """The Firefox value 'eval script base restriction' for the 'violated-directive' field is parsed
        correctly."""
        firefoxViolatedDirective = "eval script base restriction"
        assert DirectiveParser().parse(firefoxViolatedDirective) \
                == Directive.EVAL_SCRIPT_BASE_RESTRICTION()
Exemplo n.º 25
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
Exemplo n.º 26
0
 def test_no_modification_partial_URI_data_scheme_colon_slash_slash(self):
     """Ensure that an URI with only 'data' is parsed as the scheme with empty host name, not as host name."""
     uriString = "data://"
     uriExpected = URI("data", "", None, None)
     assert URIParser().parse(uriString) == uriExpected
Exemplo n.º 27
0
 def test_no_modification_partial_URI_data_scheme(self):
     """Ensure that an URI with only 'data' is parsed as the scheme with empty host name, not as host name."""
     uriString = "data"
     uriExpected = URI("data", "", None, None)
     assert URIParser(addScheme=False,
                      addPort=False).parse(uriString) == uriExpected
Exemplo n.º 28
0
 def test_no_modification_partial_URI_host_port_query(self):
     """Simple test with no modification and only host and port and query in URI."""
     uriString = "www.seclab.nu:80?query"
     uriExpected = URI(None, "www.seclab.nu", 80, None, "query")
     assert URIParser(addScheme=False,
                      addPort=False).parse(uriString) == uriExpected
Exemplo n.º 29
0
class PolicyTest(unittest.TestCase):

    sampleURI1a = URI("http", "seclab.nu", None, None, None)
    sampleURI1b = URI("http", "seclab.nu", None, None, None)
    sampleURI2 = URI("http", "seclab.ccs.neu.edu", None, None, None)
    sampleSourceExpression1 = URISourceExpression("http", "seclab.nu", None,
                                                  None)
    sampleSourceExpression2 = SelfSourceExpression.SELF()
    sampleDirective1a = Directive(
        "default-src",
        (URISourceExpression("http", "seclab.nu", None, None), ))
    sampleDirective1b = Directive(
        "default-src",
        (URISourceExpression("http", "seclab.nu", None, None), ))
    sampleDirective2 = Directive("script-src",
                                 (SourceExpression.UNSAFE_INLINE(), ))
    sampleDirective3 = Directive(
        "img-src", (URISourceExpression(None, "*", None, None), ))
    sampleDirective4 = Directive("img-src", ())
    sampleDirective5 = Directive(
        "connect-src",
        (SelfSourceExpression.SELF(),
         URISourceExpression("chrome-extension", None, None, None),
         URISourceExpression("https", "abc.seclab.nu", None, "/path")))
    sampleDirective6 = Directive(
        "style-src",
        (SourceExpression.UNSAFE_INLINE(), SelfSourceExpression.SELF()))
    sampleDirective7 = Directive("script-src",
                                 (SourceExpression.UNSAFE_EVAL(), ))
    sampleDirective8 = Directive("style-src", (SelfSourceExpression.SELF(), ))
    sampleDirective9 = Directive("default-src",
                                 (SourceExpression.UNSAFE_INLINE(), ))

    def testPolicy_str_invalid(self):
        assert str(Policy.INVALID()) == "[invalid]"

    def testPolicy_str_empty(self):
        assert str(Policy(())) == ""

    def testPolicy_str_normal(self):
        pol = Policy(
            (PolicyTest.sampleDirective1a, PolicyTest.sampleDirective2,
             PolicyTest.sampleDirective3))
        assert str(
            pol
        ) == "default-src http://seclab.nu; img-src *; script-src 'unsafe-inline'"

    def testPolicy_eq(self):
        pol1a = Policy(
            (PolicyTest.sampleDirective1a, PolicyTest.sampleDirective2,
             PolicyTest.sampleDirective3))
        pol1b = Policy(
            (PolicyTest.sampleDirective1b, PolicyTest.sampleDirective2,
             PolicyTest.sampleDirective3))
        pol2 = Policy(
            (PolicyTest.sampleDirective2, PolicyTest.sampleDirective3))
        assert Policy.INVALID() == Policy.INVALID()
        assert pol1a == pol1b
        assert hash(pol1a) == hash(pol1b)
        assert pol1a != pol2

    def testPolicy_init_duplicateType(self):
        pol = Policy(
            (PolicyTest.sampleDirective1a, PolicyTest.sampleDirective3,
             PolicyTest.sampleDirective4))
        directives = pol.getDirectives()
        assert PolicyTest.sampleDirective1a in directives and (PolicyTest.sampleDirective3 in directives \
                                                              or PolicyTest.sampleDirective4 in directives)

    def testPolicy_init_duplicateDirective(self):
        pol = Policy(
            (PolicyTest.sampleDirective1a, PolicyTest.sampleDirective1b,
             PolicyTest.sampleDirective2))
        assert pol == Policy(
            (PolicyTest.sampleDirective1a, PolicyTest.sampleDirective2))
        assert pol == Policy(
            (PolicyTest.sampleDirective1b, PolicyTest.sampleDirective2))

    def testPolicy_init_noDuplicatesHere(self):
        directives = set([
            PolicyTest.sampleDirective1a, PolicyTest.sampleDirective2,
            PolicyTest.sampleDirective5
        ])
        pol = Policy(directives)
        assert pol.getDirectives() == directives

    def testPolicy_init_removeNotRegularDirective(self):
        pol = Policy([
            PolicyTest.sampleDirective1a,
            Directive.INVALID(),
            Directive.EVAL_SCRIPT_BASE_RESTRICTION()
        ])
        expected = Policy([PolicyTest.sampleDirective1a])
        assert pol == expected

    def testPolicy_matches_invalid(self):
        """An invalid policy matches nothing."""
        selfURI = PolicyTest.sampleURI2
        assert not Policy.INVALID().matches(PolicyTest.sampleURI1a,
                                            "script-src", selfURI)
        assert not Policy.INVALID().matches(URI.INVALID(), "script-src",
                                            selfURI)
        assert not Policy.INVALID().matches(URI.EMPTY(), "script-src", selfURI)
        assert not Policy.INVALID().matches(URI.INLINE(), "script-src",
                                            selfURI)
        assert not Policy.INVALID().matches(URI.EVAL(), "script-src", selfURI)

    def testPolicy_matches_matchingDirectiveType(self):
        """Policy contains directive of resource type that matches."""
        pol = Policy(
            (PolicyTest.sampleDirective1a, PolicyTest.sampleDirective5))
        selfURI = PolicyTest.sampleURI2
        assert pol.matches(
            URI("https", "abc.seclab.nu", 443, "/path", "some-query"),
            "connect-src", selfURI)

    def testPolicy_matches_nonMatchingDirectiveTypeButDefaultMatches(self):
        """Policy contains directive of resource type that does not match
        and default directive that does match, but it should not be applied."""
        pol = Policy(
            (PolicyTest.sampleDirective1a, PolicyTest.sampleDirective5))
        selfURI = PolicyTest.sampleURI2
        assert not pol.matches(PolicyTest.sampleURI1a, "connect-src", selfURI)

    def testPolicy_matches_defaultSrcMatches(self):
        """Policy contains no directive of resource type, but a default directive that matches."""
        pol = Policy(
            (PolicyTest.sampleDirective1a, PolicyTest.sampleDirective5))
        selfURI = PolicyTest.sampleURI2
        assert pol.matches(PolicyTest.sampleURI1a, "script-src", selfURI)

    def testPolicy_matches_defaultSrcNoMatch(self):
        """Policy contains no directive of resource type, but a default directive.
        Default-src does not match."""
        pol = Policy((PolicyTest.sampleDirective1a, ))
        selfURI = PolicyTest.sampleURI1a
        assert not pol.matches(PolicyTest.sampleURI2, "img-src", selfURI)

    def testPolicy_matches_defaultSrcNotUsable(self):
        """Policy contains no directive of resource type, but a default directive.
        Default-src cannot be used in this case because not allowed for resource type."""
        pol = Policy((PolicyTest.sampleDirective1a, ))
        selfURI = PolicyTest.sampleURI2
        assert not pol.matches(PolicyTest.sampleURI1a, "form-action", selfURI)

    def testPolicy_matches_defaultSrcNotSpecified_match(self):
        """Policy contains no directive of resource type, and no default directive either.
        Should assume 'default-src *' (match for regular resources)."""
        pol = Policy((PolicyTest.sampleDirective5, ))
        selfURI = PolicyTest.sampleURI1a
        assert pol.matches(PolicyTest.sampleURI2, "script-src", selfURI)

    def testPolicy_matches_defaultSrcNotSpecified_noMatch(self):
        """Policy contains no directive of resource type, and no default directive either.
        Should assume 'default-src *' (no match for inline/eval resources)."""
        pol = Policy((PolicyTest.sampleDirective5, ))
        selfURI = PolicyTest.sampleURI1a
        assert not pol.matches(URI.INLINE(), "script-src", selfURI)
        assert not pol.matches(URI.EVAL(), "script-src", selfURI)

    def testPolicyParser_parse_normal(self):
        simplePolicy = """connect-src 'self' https://abc.seclab.nu/path chrome-extension:; img-src 'none'"""
        cspSimplePolicy = PolicyParser().parse(simplePolicy)
        print cspSimplePolicy
        assert cspSimplePolicy == Policy(
            [PolicyTest.sampleDirective4, PolicyTest.sampleDirective5])

    def testPolicyParser_parse_strict_onlyValidDirectives(self):
        """Ensures that a CSP policy does not parse in strict mode if it contains an invalid directive."""
        policy = """img-src 'none'; script-src"""
        cspPolicy = PolicyParser(strict=True).parse(policy)
        assert cspPolicy == Policy.INVALID()

    def testPolicyParser_parse_nonstrict_onlyValidDirectives(self):
        """Ensures that a CSP policy does ignore invalid portions in non-strict mode if it contains an invalid directive."""
        policy = """img-src 'none'; script-src"""
        cspPolicy = PolicyParser(strict=False).parse(policy)
        assert cspPolicy == Policy([PolicyTest.sampleDirective4])

    def testPolicyParser_parse_ignoredDirective(self):
        """Ensure that unsupported directives ('report-uri' etc.) are skipped without
         causing an error."""
        policy = """img-src *; report-uri /csp.cgi"""
        cspPolicy = PolicyParser(strict=True,
                                 ignoredTypes=("report-uri", )).parse(policy)
        assert cspPolicy == Policy([PolicyTest.sampleDirective3])

    def testPolicyParser_parse_defaultSrcRewriting(self):
        """The default directive is used for each type that is not specifically defined (if the flag is enabled)."""
        policy = """default-src 'self' http://seclab.nu; connect-src 'self' https://abc.seclab.nu/path chrome-extension:"""
        cspPolicy = PolicyParser(expandDefaultSrc=True,
                                 defaultSrcTypes=("img-src",
                                                  "connect-src")).parse(policy)
        assert cspPolicy == Policy([
            PolicyTest.sampleDirective5,
            Directive("img-src", [
                PolicyTest.sampleSourceExpression1,
                PolicyTest.sampleSourceExpression2
            ])
        ])

    def testPolicyParser_parse_noDefaultSrcRewriting(self):
        policy = """default-src 'self' http://seclab.nu"""
        cspPolicy = PolicyParser(expandDefaultSrc=False,
                                 defaultSrcTypes=("img-src",
                                                  "connect-src")).parse(policy)
        assert cspPolicy == Policy([
            Directive("default-src", [
                PolicyTest.sampleSourceExpression1,
                PolicyTest.sampleSourceExpression2
            ])
        ])

    def testPolicyParser_parse_duplicates(self):
        """The CSP standard mandates that only the first directive of each type should be used."""
        duplicatePolicy = """connect-src 'self' chrome-extension: https://abc.seclab.nu/path; """ \
                            + """font-src 'self' http://seclab.nu; """ \
                            + """connect-src 'self' https://example.com"""
        cspPolicy = PolicyParser().parse(duplicatePolicy)
        assert cspPolicy == Policy([
            PolicyTest.sampleDirective5,
            Directive("font-src", [
                PolicyTest.sampleSourceExpression1,
                PolicyTest.sampleSourceExpression2
            ])
        ])

    def testPolicy_combinedPolicy_normal(self):
        pol1 = Policy([
            PolicyTest.sampleDirective6, PolicyTest.sampleDirective2,
            PolicyTest.sampleDirective3
        ])
        pol2 = Policy(
            [PolicyTest.sampleDirective4, PolicyTest.sampleDirective7])
        expected = Policy([
            PolicyTest.sampleDirective6, PolicyTest.sampleDirective3,
            Directive("script-src", [
                SourceExpression.UNSAFE_EVAL(),
                SourceExpression.UNSAFE_INLINE()
            ])
        ])
        assert pol1.combinedPolicy(pol1) == pol1
        assert pol2.combinedPolicy(pol2) == pol2
        assert pol1.combinedPolicy(pol2) == expected
        assert pol2.combinedPolicy(pol1) == expected

    def testPolicy_combinedPolicy_invalidPolicy(self):
        pol = Policy([
            PolicyTest.sampleDirective1a, PolicyTest.sampleDirective2,
            PolicyTest.sampleDirective3
        ])
        assert pol.combinedPolicy(Policy.INVALID()) == Policy.INVALID()
        assert Policy.INVALID().combinedPolicy(pol) == Policy.INVALID()

    def testPolicy_combinedPolicy_invalidDefaultSrcAndOtherDirective(self):
        pol1 = Policy(
            [PolicyTest.sampleDirective1a, PolicyTest.sampleDirective3])
        pol2 = Policy([PolicyTest.sampleDirective9])
        assert pol1.combinedPolicy(pol2) == Policy.INVALID()
        assert pol2.combinedPolicy(pol1) == Policy.INVALID()

    def testPolicy_combinedPolicy_invalidDefaultSrcInOnePolicyOnly(self):
        pol1 = Policy([PolicyTest.sampleDirective3])
        pol2 = Policy([PolicyTest.sampleDirective9])
        assert pol1.combinedPolicy(pol2) == Policy.INVALID()
        assert pol2.combinedPolicy(pol1) == Policy.INVALID()

    def testPolicy_combinedPolicy_validDefaultSrcOnly(self):
        """Combination of two policies with default directive is possible only if both policies contain
        only a default directive."""
        pol1 = Policy([PolicyTest.sampleDirective1a])
        pol2 = Policy([PolicyTest.sampleDirective9])
        expected = Policy([
            Directive("default-src", [
                PolicyTest.sampleSourceExpression1,
                SourceExpression.UNSAFE_INLINE()
            ])
        ])
        assert pol1.combinedPolicy(pol2) == expected
        assert pol2.combinedPolicy(pol1) == expected

    def testPolicy_withoutPaths(self):
        withPaths = Policy([
            PolicyTest.sampleDirective3, PolicyTest.sampleDirective5,
            PolicyTest.sampleDirective7
        ])
        withoutPaths = Policy([
            PolicyTest.sampleDirective3,
            PolicyTest.sampleDirective5.withoutPaths(),
            PolicyTest.sampleDirective7
        ])
        assert withPaths.withoutPaths() == withoutPaths
        assert withoutPaths.withoutPaths() == withoutPaths
        assert Policy.INVALID().withoutPaths() == Policy.INVALID()

    def testPolicy_withoutPaths_schemeOnly(self):
        withPaths = Policy(
            [PolicyTest.sampleDirective3, PolicyTest.sampleDirective5])
        withoutPaths = Policy([
            PolicyTest.sampleDirective3,
            PolicyTest.sampleDirective5.withoutPaths(["http"])
        ])
        assert withPaths.withoutPaths(["http"]) == withoutPaths

    def testPolicy_asBasicPolicies_single(self):
        assert Policy.INVALID().asBasicPolicies() == set([])
        assert Policy([PolicyTest.sampleDirective1a]).asBasicPolicies() == set(
            [Policy([PolicyTest.sampleDirective1a])])

    def testPolicy_asBasicPolicies_multiple(self):
        assert Policy(
            [PolicyTest.sampleDirective1a,
             PolicyTest.sampleDirective2]).asBasicPolicies() == set([
                 Policy([PolicyTest.sampleDirective1a]),
                 Policy([PolicyTest.sampleDirective2])
             ])

    def testPolicy_asBasicPolicies_recursive(self):
        expected = set(
            map(lambda direct: Policy((direct, )),
                PolicyTest.sampleDirective5.asBasicDirectives()))
        actual = Policy([PolicyTest.sampleDirective5]).asBasicPolicies()
        assert actual == expected

    def testPolicy_isBasicPolicy(self):
        assert Policy.INVALID().isBasicPolicy() == False
        assert Policy([PolicyTest.sampleDirective6]).isBasicPolicy() == False
        assert Policy([PolicyTest.sampleDirective1a]).isBasicPolicy() == True
        assert Policy(
            [PolicyTest.sampleDirective2,
             PolicyTest.sampleDirective4]).isBasicPolicy() == False

    def testPolicy_isBasicNonePolicy(self):
        assert Policy.INVALID().isBasicNonePolicy() == False
        assert Policy([PolicyTest.sampleDirective6
                       ]).isBasicNonePolicy() == False
        assert Policy([PolicyTest.sampleDirective1a
                       ]).isBasicNonePolicy() == False
        assert Policy(
            [PolicyTest.sampleDirective2,
             PolicyTest.sampleDirective4]).isBasicNonePolicy() == False
        assert Policy([PolicyTest.sampleDirective4
                       ]).isBasicNonePolicy() == True

    def testPolicy_hasDefaultDirective(self):
        assert Policy.INVALID().hasDefaultDirective() == False
        assert Policy(
            [PolicyTest.sampleDirective2,
             PolicyTest.sampleDirective9]).hasDefaultDirective() == True
        assert Policy(
            [PolicyTest.sampleDirective5,
             PolicyTest.sampleDirective6]).hasDefaultDirective() == False

    def testPolicy_compareTo_invalid(self):
        assert Policy.INVALID().compareTo(Policy.INVALID()) == (set([]),
                                                                set([]),
                                                                set([]))
        pol = Policy([PolicyTest.sampleDirective9])
        assert pol.compareTo(Policy.INVALID()) == (set([]), set([]), set([]))
        assert Policy.INVALID().compareTo(pol) == (set([]), set([]), set([]))

    def testPolicy_compareTo_regular(self):
        pol1 = Policy(
            [PolicyTest.sampleDirective7, PolicyTest.sampleDirective8])
        pol2 = Policy(
            [PolicyTest.sampleDirective7, PolicyTest.sampleDirective9])
        assert pol1.compareTo(pol2) == (set([
            Policy([PolicyTest.sampleDirective7])
        ]), set([Policy([PolicyTest.sampleDirective8])
                 ]), set([Policy([PolicyTest.sampleDirective9])]))
        assert pol2.compareTo(pol1) == (set([
            Policy([PolicyTest.sampleDirective7])
        ]), set([Policy([PolicyTest.sampleDirective9])
                 ]), set([Policy([PolicyTest.sampleDirective8])]))
        assert pol1.compareTo(pol1) == (set([
            Policy([PolicyTest.sampleDirective7]),
            Policy([PolicyTest.sampleDirective8])
        ]), set([]), set([]))

    def testPolicy_compareTo_recursive(self):
        pol1 = Policy([PolicyTest.sampleDirective6])
        pol2 = Policy(
            [Directive("style-src", [SourceExpression.UNSAFE_INLINE()])])
        assert pol1.compareTo(pol2) == (
            set([pol2]),
            set([
                Policy([Directive("style-src", [SelfSourceExpression.SELF()])])
            ]), set([]))
Exemplo n.º 30
0
 def test_no_modification_partial_URI_viewSource(self):
     """view-source: URIs are similar to data URIs."""
     uriString = "view-source:http://www.seclab.nu/page/"
     uriExpected = URI("view-source", "http://www.seclab.nu/page/", None,
                       None)
     assert URIParser().parse(uriString) == uriExpected