From 7e2560e5896aa631c61913881c2eb590d4c575a3 Mon Sep 17 00:00:00 2001 From: Sergey Date: Tue, 23 Mar 2021 17:02:01 +0300 Subject: [PATCH] Added simple cid validation --- browser/ipfs/content_browser_client_helper.cc | 4 ++++ .../content_browser_client_helper_unittest.cc | 24 +++++++++++++++---- components/ipfs/ipfs_utils.cc | 19 +++++++++++++++ components/ipfs/ipfs_utils.h | 2 +- components/ipfs/ipfs_utils_unittest.cc | 22 +++++++++++++++++ 5 files changed, 66 insertions(+), 5 deletions(-) diff --git a/browser/ipfs/content_browser_client_helper.cc b/browser/ipfs/content_browser_client_helper.cc index 2a1102cf45d..f3a67e0ac3e 100644 --- a/browser/ipfs/content_browser_client_helper.cc +++ b/browser/ipfs/content_browser_client_helper.cc @@ -96,6 +96,10 @@ bool HandleIPFSURLReverseRewrite( if (ipfs_pos == std::string::npos && ipns_pos == std::string::npos) return false; + auto cid_end = (ipfs_pos == std::string::npos) ? ipns_pos : ipfs_pos; + if (!ipfs::IsValidCID(url->host().substr(0, cid_end))) + return false; + GURL configured_gateway = GetConfiguredBaseGateway(browser_context, chrome::GetChannel()); if (configured_gateway.port() != url->port()) diff --git a/browser/ipfs/content_browser_client_helper_unittest.cc b/browser/ipfs/content_browser_client_helper_unittest.cc index 2022f56fac1..c599c4220e0 100644 --- a/browser/ipfs/content_browser_client_helper_unittest.cc +++ b/browser/ipfs/content_browser_client_helper_unittest.cc @@ -201,8 +201,7 @@ TEST_F(ContentBrowserClientHelperUnitTest, HandleIPFSURLReverseRewriteLocal) { ipns_uri = GURL("http://test.com.ipns.localhost/"); ipns_uri = ipns_uri.ReplaceComponents(replacements); - ASSERT_TRUE(HandleIPFSURLReverseRewrite(&ipns_uri, browser_context())); - ASSERT_EQ(ipns_uri.spec(), "ipns://test.com/"); + ASSERT_FALSE(HandleIPFSURLReverseRewrite(&ipns_uri, browser_context())); } TEST_F(ContentBrowserClientHelperUnitTest, HandleIPFSURLReverseRewriteGateway) { @@ -244,9 +243,26 @@ TEST_F(ContentBrowserClientHelperUnitTest, HandleIPFSURLReverseRewriteGateway) { ASSERT_FALSE(HandleIPFSURLReverseRewrite(&ipns_uri, browser_context())); ASSERT_EQ(ipns_uri.spec(), source); - ipns_uri = GURL("http://test.com.ipns.localhost:8080/"); + source = "http://test.com.ipns.localhost:8080/"; + ipns_uri = GURL(source); + ASSERT_FALSE(HandleIPFSURLReverseRewrite(&ipns_uri, browser_context())); + ASSERT_EQ(ipns_uri.spec(), source); + + ipns_uri = GURL( + "https://bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq" + ".ipns.localhost:8080/"); ASSERT_TRUE(HandleIPFSURLReverseRewrite(&ipns_uri, browser_context())); - ASSERT_EQ(ipns_uri.spec(), "ipns://test.com/"); + ASSERT_EQ( + ipns_uri.spec(), + "ipns://bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq/"); + + ipns_uri = GURL( + "https://bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq" + ".ipfs.localhost:8080/"); + ASSERT_TRUE(HandleIPFSURLReverseRewrite(&ipns_uri, browser_context())); + ASSERT_EQ( + ipns_uri.spec(), + "ipfs://bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq/"); } TEST_F(ContentBrowserClientHelperUnitTest, HandleIPFSURLRewriteInternal) { diff --git a/components/ipfs/ipfs_utils.cc b/components/ipfs/ipfs_utils.cc index dfe3ebdfd39..57cb5e5e713 100644 --- a/components/ipfs/ipfs_utils.cc +++ b/components/ipfs/ipfs_utils.cc @@ -8,6 +8,7 @@ #include #include "base/feature_list.h" +#include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "brave/components/ipfs/features.h" #include "brave/components/ipfs/ipfs_constants.h" @@ -29,10 +30,28 @@ GURL AppendLocalPort(const std::string& port) { return gateway.ReplaceComponents(replacements); } +// Valid CID multibase prefix, "code" character +// from https://github.com/multiformats/multibase/blob/master/multibase.csv +const char kCIDv1Codes[] = "079fFvVtTbBcChkKzZmMuU"; +const char kCIDv0Prefix[] = "Qm"; + } // namespace namespace ipfs { +// Simple CID validation based on multibase table. +bool IsValidCID(const std::string& cid) { + if (!cid.size()) + return false; + if (!std::all_of(cid.begin(), cid.end(), [loc = std::locale{}](char c) { + return std::isalnum(c, loc); + })) + return false; + if (std::string(kCIDv1Codes).find(cid.at(0)) != std::string::npos) + return true; + return base::StartsWith(cid, kCIDv0Prefix); +} + bool IsIpfsDisabledByPolicy(content::BrowserContext* context) { DCHECK(context); PrefService* prefs = user_prefs::UserPrefs::Get(context); diff --git a/components/ipfs/ipfs_utils.h b/components/ipfs/ipfs_utils.h index 56a0d579eda..3518358eb61 100644 --- a/components/ipfs/ipfs_utils.h +++ b/components/ipfs/ipfs_utils.h @@ -22,7 +22,7 @@ namespace ipfs { bool IsIpfsEnabled(content::BrowserContext* context); bool IsIpfsResolveMethodDisabled(content::BrowserContext* context); bool IsIpfsDisabledByPolicy(content::BrowserContext* context); - +bool IsValidCID(const std::string& cid); bool HasIPFSPath(const GURL& url); bool IsDefaultGatewayURL(const GURL& url, content::BrowserContext* context); bool IsLocalGatewayURL(const GURL& url); diff --git a/components/ipfs/ipfs_utils_unittest.cc b/components/ipfs/ipfs_utils_unittest.cc index 0ba476fe9ba..aa265f6f2ed 100644 --- a/components/ipfs/ipfs_utils_unittest.cc +++ b/components/ipfs/ipfs_utils_unittest.cc @@ -53,6 +53,28 @@ class IpfsUtilsUnitTest : public testing::Test { GURL public_gateway_; }; +TEST_F(IpfsUtilsUnitTest, CIDValidation) { + ASSERT_TRUE(ipfs::IsValidCID( + "bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq")); + ASSERT_TRUE( + ipfs::IsValidCID("QmfM2r8seH2GiRaC4esTjeraXEachRt8ZsSeGaWTPLyMoG")); + ASSERT_TRUE( + ipfs::IsValidCID("zb2rhe5P4gXftAwvA4eXQ5HJwsER2owDyS9sKaQRRVQPn93bA")); + ASSERT_TRUE(ipfs::IsValidCID("bafkqaaa")); + ASSERT_TRUE(ipfs::IsValidCID("k51qzi5uqu5dgutdk6i1ynyzg")); + ASSERT_TRUE(ipfs::IsValidCID("7testtesttest")); + + ASSERT_FALSE( + ipfs::IsValidCID("zb2rhe5P4gXftAwvA4eXQ5HJwsER2owDyS9sKaQRRVQPn=3bA")); + ASSERT_FALSE(ipfs::IsValidCID("brantly.eth")); + ASSERT_FALSE(ipfs::IsValidCID( + "ba.ybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq")); + ASSERT_FALSE(ipfs::IsValidCID( + "ba-ybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq")); + ASSERT_FALSE(ipfs::IsValidCID( + "ba%ybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq")); +} + TEST_F(IpfsUtilsUnitTest, HasIPFSPath) { std::vector ipfs_urls( {GURL("http://localhost:48080/ipfs/"