From 5d4252284471235920dce503844ccacd9b08477a Mon Sep 17 00:00:00 2001 From: huiguangjun <40553369+huiguangjun@users.noreply.github.com> Date: Fri, 15 Dec 2023 20:18:25 +0800 Subject: [PATCH] support to verify object name strictly. (#171) --- .github/workflows/linux-clang.yml | 1 + .github/workflows/linux-gcc.yml | 1 + .../oss/client/ClientConfiguration.h | 4 ++ sdk/src/OssClientImpl.cc | 2 +- sdk/src/client/ClientConfiguration.cc | 3 +- sdk/src/utils/Utils.cc | 11 ++++ sdk/src/utils/Utils.h | 1 + test/src/Object/ObjectSignedUrlTest.cc | 50 +++++++++++++++++++ test/src/Other/UtilsFunctionTest.cc | 19 +++++++ 9 files changed, 90 insertions(+), 2 deletions(-) diff --git a/.github/workflows/linux-clang.yml b/.github/workflows/linux-clang.yml index 066fd9b..4742fbe 100644 --- a/.github/workflows/linux-clang.yml +++ b/.github/workflows/linux-clang.yml @@ -20,6 +20,7 @@ jobs: - name: Install Dependencies run: | + sudo apt-get update sudo apt-get install curl libssl-dev libcurl4-openssl-dev - name: configure cmake diff --git a/.github/workflows/linux-gcc.yml b/.github/workflows/linux-gcc.yml index 7c31149..3fabb4a 100644 --- a/.github/workflows/linux-gcc.yml +++ b/.github/workflows/linux-gcc.yml @@ -20,6 +20,7 @@ jobs: - name: Install Dependencies run: | + sudo apt-get update sudo apt-get install curl libssl-dev libcurl4-openssl-dev - name: checkout gcc version diff --git a/sdk/include/alibabacloud/oss/client/ClientConfiguration.h b/sdk/include/alibabacloud/oss/client/ClientConfiguration.h index 613b412..0ee4e0a 100644 --- a/sdk/include/alibabacloud/oss/client/ClientConfiguration.h +++ b/sdk/include/alibabacloud/oss/client/ClientConfiguration.h @@ -125,6 +125,10 @@ namespace OSS * enable or disable path style, default is false. */ bool isPathStyle; + /** + * enable or disable verify object name strictly. defualt is true + */ + bool isVerifyObjectStrict; }; } } diff --git a/sdk/src/OssClientImpl.cc b/sdk/src/OssClientImpl.cc index ee38619..a5ca209 100644 --- a/sdk/src/OssClientImpl.cc +++ b/sdk/src/OssClientImpl.cc @@ -1288,7 +1288,7 @@ GetObjectTaggingOutcome OssClientImpl::GetObjectTagging(const GetObjectTaggingRe StringOutcome OssClientImpl::GeneratePresignedUrl(const GeneratePresignedUrlRequest &request) const { if (!IsValidBucketName(request.bucket_) || - !IsValidObjectKey(request.key_)) { + !IsValidObjectKey(request.key_, configuration().isVerifyObjectStrict)) { return StringOutcome(OssError("ValidateError", "The Bucket or Key is invalid.")); } diff --git a/sdk/src/client/ClientConfiguration.cc b/sdk/src/client/ClientConfiguration.cc index 93fcb7d..ebce60d 100644 --- a/sdk/src/client/ClientConfiguration.cc +++ b/sdk/src/client/ClientConfiguration.cc @@ -116,7 +116,8 @@ ClientConfiguration::ClientConfiguration() : recvRateLimiter(nullptr), executor(nullptr), httpClient(nullptr), - isPathStyle(false) + isPathStyle(false), + isVerifyObjectStrict(true) { } diff --git a/sdk/src/utils/Utils.cc b/sdk/src/utils/Utils.cc index 6a521f9..40ce980 100644 --- a/sdk/src/utils/Utils.cc +++ b/sdk/src/utils/Utils.cc @@ -598,6 +598,17 @@ bool AlibabaCloud::OSS::IsValidBucketName(const std::string &bucketName) return key.size() <= ObjectNameLengthLimit; } + bool AlibabaCloud::OSS::IsValidObjectKey(const std::string& key, bool strict) + { + if (key.empty() || !key.compare(0, 1, "\\", 1)) + return false; + + if (strict && !key.compare(0, 1, "?", 1)) + return false; + + return key.size() <= ObjectNameLengthLimit; + } + bool AlibabaCloud::OSS::IsValidLoggingPrefix(const std::string &prefix) { if (prefix.empty()) diff --git a/sdk/src/utils/Utils.h b/sdk/src/utils/Utils.h index 9f5af7e..11d4659 100644 --- a/sdk/src/utils/Utils.h +++ b/sdk/src/utils/Utils.h @@ -66,6 +66,7 @@ namespace OSS bool IsIp(const std::string &host); bool IsValidBucketName(const std::string &bucketName); bool IsValidObjectKey(const std::string &key); + bool IsValidObjectKey(const std::string& key, bool strict); bool IsValidLoggingPrefix(const std::string &prefix); bool IsValidChannelName(const std::string &channelName); bool IsValidPlayListName(const std::string &playListName); diff --git a/test/src/Object/ObjectSignedUrlTest.cc b/test/src/Object/ObjectSignedUrlTest.cc index b4a17d5..63b4915 100644 --- a/test/src/Object/ObjectSignedUrlTest.cc +++ b/test/src/Object/ObjectSignedUrlTest.cc @@ -667,6 +667,56 @@ TEST_F(ObjectSignedUrlTest, UnencodedSlashTest) } +TEST_F(ObjectSignedUrlTest, VerifyObjctNameStrictTest) +{ + std::string key = "123?"; + GeneratePresignedUrlRequest request= GeneratePresignedUrlRequest(BucketName, key, Http::Put); + auto urlOutcome = Client->GeneratePresignedUrl(request); + EXPECT_EQ(urlOutcome.isSuccess(), true); + EXPECT_TRUE(urlOutcome.result().find("123%3F?") != std::string::npos); + + key = "123?321"; + request = GeneratePresignedUrlRequest(BucketName, key, Http::Put); + urlOutcome = Client->GeneratePresignedUrl(request); + EXPECT_EQ(urlOutcome.isSuccess(), true); + EXPECT_TRUE(urlOutcome.result().find("123%3F321?") != std::string::npos); + + key = "?123"; + request = GeneratePresignedUrlRequest(BucketName, key, Http::Put); + urlOutcome = Client->GeneratePresignedUrl(request); + EXPECT_EQ(urlOutcome.isSuccess(), false); + EXPECT_TRUE(urlOutcome.error().Message().find("The Bucket or Key is invalid.") != std::string::npos); + + key = "?"; + request = GeneratePresignedUrlRequest(BucketName, key, Http::Put); + urlOutcome = Client->GeneratePresignedUrl(request); + EXPECT_EQ(urlOutcome.isSuccess(), false); + EXPECT_TRUE(urlOutcome.error().Message().find("The Bucket or Key is invalid.") != std::string::npos); + + ClientConfiguration conf; + EXPECT_TRUE(conf.isVerifyObjectStrict); + conf.isVerifyObjectStrict = false; + auto c = std::make_shared(Config::Endpoint, Config::AccessKeyId, Config::AccessKeySecret, conf); + + key = "123?321"; + request = GeneratePresignedUrlRequest(BucketName, key, Http::Put); + urlOutcome = c->GeneratePresignedUrl(request); + EXPECT_EQ(urlOutcome.isSuccess(), true); + EXPECT_TRUE(urlOutcome.result().find("/123%3F321?") != std::string::npos); + + key = "?123"; + request = GeneratePresignedUrlRequest(BucketName, key, Http::Put); + urlOutcome = c->GeneratePresignedUrl(request); + EXPECT_EQ(urlOutcome.isSuccess(), true); + EXPECT_TRUE(urlOutcome.result().find("/%3F123") != std::string::npos); + + key = "?"; + request = GeneratePresignedUrlRequest(BucketName, key, Http::Put); + urlOutcome = c->GeneratePresignedUrl(request); + EXPECT_EQ(urlOutcome.isSuccess(), true); + EXPECT_TRUE(urlOutcome.result().find("/%3F?") != std::string::npos); +} + } } \ No newline at end of file diff --git a/test/src/Other/UtilsFunctionTest.cc b/test/src/Other/UtilsFunctionTest.cc index ea546d6..72a28a5 100644 --- a/test/src/Other/UtilsFunctionTest.cc +++ b/test/src/Other/UtilsFunctionTest.cc @@ -1069,5 +1069,24 @@ TEST_F(UtilsFunctionTest, IsValidEndpointTest) EXPECT_EQ(IsValidEndpoint(""), false); } +TEST_F(UtilsFunctionTest, IsValidObjectKeyTest) +{ + EXPECT_EQ(IsValidObjectKey("123"), true); + EXPECT_EQ(IsValidObjectKey(""), false); + + EXPECT_EQ(IsValidObjectKey("123", true), true); + EXPECT_EQ(IsValidObjectKey("", true), false); + + EXPECT_EQ(IsValidObjectKey("?123", true), false); + EXPECT_EQ(IsValidObjectKey("?", true), false); + EXPECT_EQ(IsValidObjectKey("1?23", true), true); + EXPECT_EQ(IsValidObjectKey(" ?", true), true); + + EXPECT_EQ(IsValidObjectKey("?123", false), true); + EXPECT_EQ(IsValidObjectKey("?", false), true); + EXPECT_EQ(IsValidObjectKey("123?", false), true); + EXPECT_EQ(IsValidObjectKey(" ?", false), true); +} + } }