示例#1
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
示例#2
0
 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)
示例#3
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
示例#4
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)
示例#5
0
 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)
示例#6
0
 def test_InvalidSourceExpression_match(self):
     """The invalid source expression does not match anything."""
     srcExpr = SourceExpression.INVALID()
     selfURI = SourceExpressionTest.uri_chromeExtension
     assert not srcExpr.matches(SourceExpressionTest.uri_empty, selfURI)
     assert not srcExpr.matches(SourceExpressionTest.uri_urlFull, selfURI)
     assert not srcExpr.matches(SourceExpressionTest.uri_urlSubstring,
                                selfURI)
     assert not srcExpr.matches(SourceExpressionTest.uri_domain, selfURI)
     assert not srcExpr.matches(SourceExpressionTest.uri_data, selfURI)
     assert not srcExpr.matches(URI.INVALID(), selfURI)
     assert not srcExpr.matches(URI.EVAL(), selfURI)
     assert not srcExpr.matches(URI.INLINE(), selfURI)
示例#7
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)
示例#8
0
 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()
示例#9
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
示例#10
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
示例#11
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
示例#12
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
示例#13
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
示例#14
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
示例#15
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
示例#16
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
示例#17
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
示例#18
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
示例#19
0
 def test_URISourceExpression_match_star(self):
     "A source expression that should match everything (except for special URIs)."
     srcExpr = URISourceExpression(None, "*", None, None)
     selfURI = SourceExpressionTest.uri_chromeExtension
     assert srcExpr.matches(SourceExpressionTest.uri_chromeExtension,
                            selfURI)
     assert srcExpr.matches(SourceExpressionTest.uri_urlFull, selfURI)
     assert srcExpr.matches(SourceExpressionTest.uri_urlFull_secure,
                            selfURI)
     assert srcExpr.matches(SourceExpressionTest.uri_urlFull_other, selfURI)
     assert not srcExpr.matches(SourceExpressionTest.uri_empty, selfURI)
     assert srcExpr.matches(SourceExpressionTest.uri_domain, selfURI)
     assert srcExpr.matches(SourceExpressionTest.uri_data, selfURI)
     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)
示例#20
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)
示例#21
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()
示例#22
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
示例#23
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
示例#24
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
示例#25
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]"
示例#26
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
示例#27
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
示例#28
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
示例#29
0
 def test_EvalInlineSourceExpression_match(self):
     """The source expressions 'unsafe-inline' and 'unsafe-eval' do not match any URI."""
     srcExprEval = SourceExpression.UNSAFE_EVAL()
     srcExprInline = SourceExpression.UNSAFE_INLINE()
     selfURI = SourceExpressionTest.uri_chromeExtension
     assert not srcExprEval.matches(SourceExpressionTest.uri_empty, selfURI)
     assert not srcExprInline.matches(SourceExpressionTest.uri_empty,
                                      selfURI)
     assert not srcExprEval.matches(URI.INVALID(), selfURI)
     assert not srcExprInline.matches(URI.INVALID(), selfURI)
     assert srcExprInline.matches(URI.INLINE(), selfURI)
     assert not srcExprInline.matches(URI.EVAL(), selfURI)
     assert not srcExprEval.matches(URI.INLINE(), selfURI)
     assert srcExprEval.matches(URI.EVAL(), selfURI)
示例#30
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
示例#31
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([]))
示例#32
0
 def test_remove_path(self):
     """Checks that the path and query are properly removed from a URI object."""
     inputURI = URI("https", "seclab.nu", 443, "/index.html", "query=value")
     expectedURI = URI("https", "seclab.nu", 443, None, None)
     assert inputURI.removePath() == expectedURI
     assert URI.INVALID().removePath() == URI.INVALID()