Index: Source/core/frame/SubresourceIntegrityTest.cpp |
diff --git a/Source/core/frame/SubresourceIntegrityTest.cpp b/Source/core/frame/SubresourceIntegrityTest.cpp |
index c97c943ffa088a127fbc2cdddbc99e2c0c7b9a6d..abf6d87f9e88efeae6b0701cddbdf749f58cc286 100644 |
--- a/Source/core/frame/SubresourceIntegrityTest.cpp |
+++ b/Source/core/frame/SubresourceIntegrityTest.cpp |
@@ -18,96 +18,206 @@ |
namespace blink { |
static const char kBasicScript[] = "alert('test');"; |
-static const char kSha256Integrity[] = "ni://sha256;GAF48QOoxRvu0gZAmQivUdJPyBacqznBAXwnkfpmQX4="; |
-static const char kSha384Intgrity[] = "ni://sha384;nep3XpvhUxpCMOVXIFPecThAqdY/uVeiD4kXSqXpx0YJUWU4fTTaFgciTuZk7fmE"; |
-static const char kSha512Integrity[] = "ni://sha512;TXkJw18PqlVlEUXXjeXbGetop1TKB3wYQIp1/ihxCOFGUfG9TYOaA1MlkpTAqSV6yaevLO8Tj5pgH1JmZ++ItA=="; |
-static const char kSha384IntegrityLabeledAs256[] = "ni://sha256;nep3XpvhUxpCMOVXIFPecThAqdY/uVeiD4kXSqXpx0YJUWU4fTTaFgciTuZk7fmE"; |
-static const char kUnsupportedHashFunctionIntegrity[] = "ni://sha1;JfLW308qMPKfb4DaHpUBEESwuPc="; |
+static const char kSha256Integrity[] = "ni:///sha256;GAF48QOoxRvu0gZAmQivUdJPyBacqznBAXwnkfpmQX4="; |
+static const char kSha384Integrity[] = "ni:///sha384;nep3XpvhUxpCMOVXIFPecThAqdY/uVeiD4kXSqXpx0YJUWU4fTTaFgciTuZk7fmE"; |
+static const char kSha512Integrity[] = "ni:///sha512;TXkJw18PqlVlEUXXjeXbGetop1TKB3wYQIp1/ihxCOFGUfG9TYOaA1MlkpTAqSV6yaevLO8Tj5pgH1JmZ++ItA=="; |
+static const char kSha384IntegrityLabeledAs256[] = "ni:///sha256;nep3XpvhUxpCMOVXIFPecThAqdY/uVeiD4kXSqXpx0YJUWU4fTTaFgciTuZk7fmE"; |
+static const char kUnsupportedHashFunctionIntegrity[] = "ni:///sha1;JfLW308qMPKfb4DaHpUBEESwuPc="; |
+ |
+class SubresourceIntegrityTest : public ::testing::Test { |
+public: |
+ SubresourceIntegrityTest() |
+ : secureURL(ParsedURLString, "https://example.test:443") |
+ , insecureURL(ParsedURLString, "http://example.test:80") |
+ , secureOrigin(SecurityOrigin::create(secureURL)) |
+ , insecureOrigin(SecurityOrigin::create(insecureURL)) |
+ { |
+ } |
+ |
+protected: |
+ virtual void SetUp() |
+ { |
+ document = Document::create(); |
+ scriptElement = HTMLScriptElement::create(*document, true); |
+ } |
+ |
+ void expectAlgorithm(const String& text, HashAlgorithm expectedAlgorithm) |
+ { |
+ Vector<UChar> characters; |
+ text.appendTo(characters); |
+ const UChar* position = characters.data(); |
+ const UChar* end = characters.end(); |
+ HashAlgorithm algorithm; |
+ |
+ EXPECT_TRUE(SubresourceIntegrity::parseAlgorithm(position, end, algorithm)); |
+ EXPECT_EQ(expectedAlgorithm, algorithm); |
+ EXPECT_EQ(';', *position); |
+ } |
+ |
+ void expectAlgorithmFailure(const String& text) |
+ { |
+ Vector<UChar> characters; |
+ text.appendTo(characters); |
+ const UChar* position = characters.data(); |
+ const UChar* begin = characters.data(); |
+ const UChar* end = characters.end(); |
+ HashAlgorithm algorithm; |
+ |
+ EXPECT_FALSE(SubresourceIntegrity::parseAlgorithm(position, end, algorithm)); |
+ EXPECT_EQ(begin, position); |
+ } |
+ |
+ void expectDigest(const String& text, const char* expectedDigest) |
+ { |
+ Vector<UChar> characters; |
+ text.appendTo(characters); |
+ const UChar* position = characters.data(); |
+ const UChar* end = characters.end(); |
+ String digest; |
+ |
+ EXPECT_TRUE(SubresourceIntegrity::parseDigest(position, end, digest)); |
+ EXPECT_EQ(expectedDigest, digest); |
+ } |
+ |
+ void expectDigestFailure(const String& text) |
+ { |
+ Vector<UChar> characters; |
+ text.appendTo(characters); |
+ const UChar* position = characters.data(); |
+ const UChar* end = characters.end(); |
+ String digest; |
+ |
+ EXPECT_FALSE(SubresourceIntegrity::parseDigest(position, end, digest)); |
+ EXPECT_TRUE(digest.isEmpty()); |
+ } |
+ |
+ void expectParse(const char* integrityAttribute, const char* expectedDigest, HashAlgorithm expectedAlgorithm) |
+ { |
+ String digest; |
+ HashAlgorithm algorithm; |
+ |
+ EXPECT_TRUE(SubresourceIntegrity::parseIntegrityAttribute(integrityAttribute, digest, algorithm, *document)); |
+ EXPECT_EQ(expectedDigest, digest); |
+ EXPECT_EQ(expectedAlgorithm, algorithm); |
+ } |
+ |
+ void expectParseFailure(const char* integrityAttribute) |
+ { |
+ String digest; |
+ HashAlgorithm algorithm; |
+ |
+ EXPECT_FALSE(SubresourceIntegrity::parseIntegrityAttribute(integrityAttribute, digest, algorithm, *document)); |
+ } |
+ |
+ void expectIntegrity(const char* integrity, const char* script, const KURL& url) |
+ { |
+ scriptElement->setAttribute(HTMLNames::integrityAttr, integrity); |
+ EXPECT_TRUE(SubresourceIntegrity::CheckSubresourceIntegrity(*scriptElement, script, url)); |
+ } |
+ |
+ void expectIntegrityFailure(const char* integrity, const char* script, const KURL& url) |
+ { |
+ scriptElement->setAttribute(HTMLNames::integrityAttr, integrity); |
+ EXPECT_FALSE(SubresourceIntegrity::CheckSubresourceIntegrity(*scriptElement, script, url)); |
+ } |
+ |
+ KURL secureURL; |
+ KURL insecureURL; |
+ RefPtr<SecurityOrigin> secureOrigin; |
+ RefPtr<SecurityOrigin> insecureOrigin; |
+ |
+ RefPtrWillBeRawPtr<Document> document; |
+ RefPtrWillBeRawPtr<HTMLScriptElement> scriptElement; |
+}; |
+ |
+TEST_F(SubresourceIntegrityTest, ParseAlgorithm) |
+{ |
+ expectAlgorithm("sha256;", HashAlgorithmSha256); |
+ expectAlgorithm("sha384;", HashAlgorithmSha384); |
+ expectAlgorithm("sha512;", HashAlgorithmSha512); |
+ |
+ expectAlgorithmFailure("sha1;"); |
+ expectAlgorithmFailure("sha-1;"); |
+ expectAlgorithmFailure("sha-256;"); |
+ expectAlgorithmFailure("sha-384;"); |
+ expectAlgorithmFailure("sha-512;"); |
+} |
-TEST(SubresourceIntegrityTest, CheckSubresourceIntegrity) |
+TEST_F(SubresourceIntegrityTest, ParseDigest) |
{ |
- KURL secureKURL(KURL(), "https://foobar.com:443"); |
- KURL insecureKURL(KURL(), "http://foobar.com:80"); |
- RefPtr<SecurityOrigin> secureOrigin = SecurityOrigin::create(secureKURL); |
- RefPtr<SecurityOrigin> insecureOrigin = SecurityOrigin::create(insecureKURL); |
- RefPtrWillBeRawPtr<Document> document = Document::create(); |
- RefPtrWillBeRawPtr<HTMLScriptElement> scriptElement = HTMLScriptElement::create(*document, true); |
+ expectDigest("abcdefg", "abcdefg"); |
+ expectDigest("abcdefg?", "abcdefg"); |
- // Verify basic sha256, sha384, and sha512 integrity checks. |
- document->updateSecurityOrigin(secureOrigin->isolatedCopy()); |
- scriptElement->setAttribute(HTMLNames::integrityAttr, kSha256Integrity); |
- EXPECT_TRUE(SubresourceIntegrity::CheckSubresourceIntegrity(*scriptElement, kBasicScript, secureKURL)); |
- scriptElement->setAttribute(HTMLNames::integrityAttr, kSha384Intgrity); |
- EXPECT_TRUE(SubresourceIntegrity::CheckSubresourceIntegrity(*scriptElement, kBasicScript, secureKURL)); |
- scriptElement->setAttribute(HTMLNames::integrityAttr, kSha512Integrity); |
- EXPECT_TRUE(SubresourceIntegrity::CheckSubresourceIntegrity(*scriptElement, kBasicScript, secureKURL)); |
+ expectDigestFailure("?"); |
+ expectDigestFailure("&&&foobar&&&"); |
+ expectDigestFailure("\x01\x02\x03\x04"); |
+} |
- // The hash label must match the hash value. |
- scriptElement->setAttribute(HTMLNames::integrityAttr, kSha384IntegrityLabeledAs256); |
- EXPECT_FALSE(SubresourceIntegrity::CheckSubresourceIntegrity(*scriptElement, kBasicScript, secureKURL)); |
+// |
+// End-to-end parsing tests. |
+// |
- scriptElement->setAttribute(HTMLNames::integrityAttr, kSha256Integrity); |
- // Check should fail if the document is not on an authenticated origin or |
- // if the resource is not on an authenticated origin. |
- document->updateSecurityOrigin(insecureOrigin->isolatedCopy()); |
- EXPECT_FALSE(SubresourceIntegrity::CheckSubresourceIntegrity(*scriptElement, kBasicScript, secureKURL)); |
+TEST_F(SubresourceIntegrityTest, Parsing) |
+{ |
+ expectParseFailure(""); |
+ expectParseFailure("not/really/a/valid/anything"); |
+ expectParseFailure("foobar:///sha256;abcdefg"); |
+ expectParseFailure("ni://sha256;abcdefg"); |
+ expectParseFailure("ni:///not-sha256-at-all;abcdefg"); |
+ expectParseFailure("ni:///sha256;&&&foobar&&&"); |
+ expectParseFailure("ni:///sha256;\x01\x02\x03\x04"); |
+ |
+ expectParse( |
+ "ni:///sha256;BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", |
+ "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", |
+ HashAlgorithmSha256); |
+ |
+ expectParse( |
+ " ni:///sha256;BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE= ", |
+ "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", |
+ HashAlgorithmSha256); |
+ |
+ expectParse( |
+ "ni:///sha384;XVVXBGoYw6AJOh9J/Z8pBDMVVPfkBpngexkA7JqZu8d5GENND6TEIup/tA1v5GPr", |
+ "XVVXBGoYw6AJOh9J/Z8pBDMVVPfkBpngexkA7JqZu8d5GENND6TEIup/tA1v5GPr", |
+ HashAlgorithmSha384); |
+ |
+ expectParse( |
+ "ni:///sha512;tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ+07yMK81ytlg0MPaIrPAjcHqba5csorDWtKg==", |
+ "tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ+07yMK81ytlg0MPaIrPAjcHqba5csorDWtKg==", |
+ HashAlgorithmSha512); |
+} |
+ |
+// |
+// End-to-end tests of ::CheckSubresourceIntegrity. |
+// |
+ |
+TEST_F(SubresourceIntegrityTest, CheckSubresourceIntegrityInSecureOrigin) |
+{ |
document->updateSecurityOrigin(secureOrigin->isolatedCopy()); |
- EXPECT_FALSE(SubresourceIntegrity::CheckSubresourceIntegrity(*scriptElement, kBasicScript, insecureKURL)); |
- scriptElement->setAttribute(HTMLNames::integrityAttr, kUnsupportedHashFunctionIntegrity); |
- EXPECT_FALSE(SubresourceIntegrity::CheckSubresourceIntegrity(*scriptElement, kBasicScript, insecureKURL)); |
+ // Verify basic sha256, sha384, and sha512 integrity checks. |
+ expectIntegrity(kSha256Integrity, kBasicScript, secureURL); |
+ expectIntegrity(kSha384Integrity, kBasicScript, secureURL); |
+ expectIntegrity(kSha512Integrity, kBasicScript, secureURL); |
+ |
+ // The hash label must match the hash value. |
+ expectIntegrityFailure(kSha384IntegrityLabeledAs256, kBasicScript, secureURL); |
+ |
+ // Unsupported hash functions should fail. |
+ expectIntegrityFailure(kUnsupportedHashFunctionIntegrity, kBasicScript, secureURL); |
} |
-TEST(SubresourceIntegrityTest, Parsing) |
+TEST_F(SubresourceIntegrityTest, CheckSubresourceIntegrityInInsecureOrigin) |
{ |
- String attribute; |
- String integrity; |
- HashAlgorithm algorithm; |
- |
- // Verify that empty attribute is not valid. |
- EXPECT_FALSE(SubresourceIntegrity::parseIntegrityAttribute(attribute, integrity, algorithm)); |
- |
- // Valid sha256 attribute |
- attribute = "ni://sha256;BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE="; |
- EXPECT_TRUE(SubresourceIntegrity::parseIntegrityAttribute(attribute, integrity, algorithm)); |
- EXPECT_EQ(integrity, "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE="); |
- EXPECT_EQ(algorithm, HashAlgorithmSha256); |
- |
- // Another valid sha256 attribute, but this time with whitespace |
- attribute = " ni://sha256;BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE= "; |
- EXPECT_TRUE(SubresourceIntegrity::parseIntegrityAttribute(attribute, integrity, algorithm)); |
- EXPECT_EQ(integrity, "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE="); |
- EXPECT_EQ(algorithm, HashAlgorithmSha256); |
- |
- // Valid sha384 attribute |
- attribute = "ni://sha384;XVVXBGoYw6AJOh9J/Z8pBDMVVPfkBpngexkA7JqZu8d5GENND6TEIup/tA1v5GPr"; |
- EXPECT_TRUE(SubresourceIntegrity::parseIntegrityAttribute(attribute, integrity, algorithm)); |
- EXPECT_EQ(integrity, "XVVXBGoYw6AJOh9J/Z8pBDMVVPfkBpngexkA7JqZu8d5GENND6TEIup/tA1v5GPr"); |
- EXPECT_EQ(algorithm, HashAlgorithmSha384); |
- |
- // Valid sha512 attribute |
- attribute = "ni://sha512;tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ+07yMK81ytlg0MPaIrPAjcHqba5csorDWtKg=="; |
- EXPECT_TRUE(SubresourceIntegrity::parseIntegrityAttribute(attribute, integrity, algorithm)); |
- EXPECT_EQ(integrity, "tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ+07yMK81ytlg0MPaIrPAjcHqba5csorDWtKg=="); |
- EXPECT_EQ(algorithm, HashAlgorithmSha512); |
- |
- // Invalid prefix |
- attribute = "foobar://sha256;BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE="; |
- EXPECT_FALSE(SubresourceIntegrity::parseIntegrityAttribute(attribute, integrity, algorithm)); |
- |
- // Invalid hash function |
- attribute = "ni://not_a_hash_function;BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE="; |
- EXPECT_FALSE(SubresourceIntegrity::parseIntegrityAttribute(attribute, integrity, algorithm)); |
- |
- // Invalid integrity (not base64) |
- attribute = "ni://sha256;&&&foobar&&&"; |
- EXPECT_FALSE(SubresourceIntegrity::parseIntegrityAttribute(attribute, integrity, algorithm)); |
- attribute = "ni://sha256;\x01\x02\x03\x04"; |
- EXPECT_FALSE(SubresourceIntegrity::parseIntegrityAttribute(attribute, integrity, algorithm)); |
- |
- // Just integrity |
- attribute = "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE="; |
- EXPECT_FALSE(SubresourceIntegrity::parseIntegrityAttribute(attribute, integrity, algorithm)); |
+ // The same checks as CheckSubresourceIntegrityInSecureOrigin should fail here. |
+ document->updateSecurityOrigin(insecureOrigin->isolatedCopy()); |
+ |
+ expectIntegrityFailure(kSha256Integrity, kBasicScript, secureURL); |
+ expectIntegrityFailure(kSha384Integrity, kBasicScript, secureURL); |
+ expectIntegrityFailure(kSha512Integrity, kBasicScript, secureURL); |
+ expectIntegrityFailure(kSha384IntegrityLabeledAs256, kBasicScript, secureURL); |
+ expectIntegrityFailure(kUnsupportedHashFunctionIntegrity, kBasicScript, secureURL); |
} |
} // namespace blink |