From 69081536bd44f0c555ca55ac428e2022ab541c45 Mon Sep 17 00:00:00 2001 From: ws Date: Thu, 7 Dec 2023 15:46:18 +0800 Subject: [PATCH 1/2] support to verify object name strictly. --- AliyunOSSSDK/OSSClient.m | 12 ++ AliyunOSSSDK/OSSModel.h | 3 + AliyunOSSSDK/OSSModel.m | 1 + AliyunOSSSDK/OSSUtil.h | 1 + AliyunOSSSDK/OSSUtil.m | 7 ++ AliyunOSSiOSTests/AliyunOSSiOSTests.m | 4 + AliyunOSSiOSTests/OSSConfigurationTest.m | 135 +++++++++++++++++++++++ 7 files changed, 163 insertions(+) diff --git a/AliyunOSSSDK/OSSClient.m b/AliyunOSSSDK/OSSClient.m index 9f6fe11..2d6c21d 100644 --- a/AliyunOSSSDK/OSSClient.m +++ b/AliyunOSSSDK/OSSClient.m @@ -1988,6 +1988,12 @@ - (OSSTask *)presignConstrainURLWithBucketName:(NSString *)bucketName withHeaders:(NSDictionary *)headers { return [[OSSTask taskWithResult:nil] continueWithBlock:^id(OSSTask *task) { + if (objectKey && ![OSSUtil validateObjectKey:objectKey strict:self.clientConfiguration.isVerifyObjectStrictEnable]) { + return [OSSTask taskWithError:[NSError errorWithDomain:OSSClientErrorDomain + code:OSSClientErrorCodeInvalidArgument + userInfo:@{OSSErrorMessageTOKEN: @"Object key invalid"}]]; + } + NSString * resource = [NSString stringWithFormat:@"/%@/%@", bucketName, objectKey]; NSString * expires = [@((int64_t)[[NSDate oss_clockSkewFixedDate] timeIntervalSince1970] + interval) stringValue]; NSString * xossHeader = @""; @@ -2114,6 +2120,12 @@ - (OSSTask *)presignPublicURLWithBucketName:(NSString *)bucketName withParameters:(NSDictionary *)parameters { return [[OSSTask taskWithResult:nil] continueWithBlock:^id(OSSTask *task) { + if (objectKey && ![OSSUtil validateObjectKey:objectKey strict:self.clientConfiguration.isVerifyObjectStrictEnable]) { + return [OSSTask taskWithError:[NSError errorWithDomain:OSSClientErrorDomain + code:OSSClientErrorCodeInvalidArgument + userInfo:@{OSSErrorMessageTOKEN: @"Object key invalid"}]]; + } + BOOL isPathStyle = false; NSURL * endpointURL = [NSURL URLWithString:self.endpoint]; NSString * host = endpointURL.host; diff --git a/AliyunOSSSDK/OSSModel.h b/AliyunOSSSDK/OSSModel.h index 2b2d1b4..ef39807 100644 --- a/AliyunOSSSDK/OSSModel.h +++ b/AliyunOSSSDK/OSSModel.h @@ -204,6 +204,9 @@ Sets the session Id for background file transmission */ @property (nonatomic, assign) BOOL isPathStyleAccessEnable; +/// Sets the flag of verifying object name strictly. +@property (nonatomic, assign) BOOL isVerifyObjectStrictEnable; + /** Sets the flag of using custom path prefix to access the endpoint. By default it's false. */ diff --git a/AliyunOSSSDK/OSSModel.m b/AliyunOSSSDK/OSSModel.m index b971c25..515fdb8 100644 --- a/AliyunOSSSDK/OSSModel.m +++ b/AliyunOSSSDK/OSSModel.m @@ -302,6 +302,7 @@ - (instancetype)init { self.cnameExcludeList = @[]; self.isAllowUACarrySystemInfo = YES; self.isFollowRedirectsEnable = YES; + self.isVerifyObjectStrictEnable = YES; } return self; } diff --git a/AliyunOSSSDK/OSSUtil.h b/AliyunOSSSDK/OSSUtil.h index ea3f4e2..4972b7c 100644 --- a/AliyunOSSSDK/OSSUtil.h +++ b/AliyunOSSSDK/OSSUtil.h @@ -26,6 +26,7 @@ + (NSData *)constructHttpBodyForCreateBucketWithLocation:(NSString *)location __attribute__((deprecated("deprecated!"))); + (BOOL)validateBucketName:(NSString *)bucketName; + (BOOL)validateObjectKey:(NSString *)objectKey; ++ (BOOL)validateObjectKey:(NSString *)objectKey strict:(BOOL)strict; + (BOOL)isOssOriginBucketHost:(NSString *)host; + (NSString *)getIpByHost:(NSString *)host; + (BOOL)isNetworkDelegateState; diff --git a/AliyunOSSSDK/OSSUtil.m b/AliyunOSSSDK/OSSUtil.m index 8b1ab92..5783a4f 100644 --- a/AliyunOSSSDK/OSSUtil.m +++ b/AliyunOSSSDK/OSSUtil.m @@ -156,6 +156,10 @@ + (BOOL)validateBucketName:(NSString *)bucketName { } + (BOOL)validateObjectKey:(NSString *)objectKey { + return [self validateObjectKey:objectKey strict:false]; +} + ++ (BOOL)validateObjectKey:(NSString *)objectKey strict:(BOOL)strict { if (objectKey == nil) { return false; } @@ -172,6 +176,9 @@ + (BOOL)validateObjectKey:(NSString *)objectKey { if (firstChar == '/' || firstChar == '\\') { return false; } + if (strict && firstChar == '?') { + return false; + } return true; } diff --git a/AliyunOSSiOSTests/AliyunOSSiOSTests.m b/AliyunOSSiOSTests/AliyunOSSiOSTests.m index c9cf4b4..9afd441 100644 --- a/AliyunOSSiOSTests/AliyunOSSiOSTests.m +++ b/AliyunOSSiOSTests/AliyunOSSiOSTests.m @@ -1336,6 +1336,10 @@ - (void)testValidateName { XCTAssertFalse([OSSUtil validateBucketName:@"abc-abc-"]); XCTAssertFalse([OSSUtil validateObjectKey:@"/abc"]); + XCTAssertFalse([OSSUtil validateObjectKey:@"?abc" strict:YES]); + XCTAssertTrue([OSSUtil validateObjectKey:@"abc" strict:YES]); + XCTAssertTrue([OSSUtil validateObjectKey:@"?abc" strict:NO]); + XCTAssertTrue([OSSUtil validateObjectKey:@"?abc"]); XCTAssertFalse([OSSUtil validateObjectKey:@"\\abc"]); XCTAssertFalse([OSSUtil validateObjectKey:@"\\中文"]); XCTAssertTrue([OSSUtil validateObjectKey:@"abc"]); diff --git a/AliyunOSSiOSTests/OSSConfigurationTest.m b/AliyunOSSiOSTests/OSSConfigurationTest.m index e9b06e8..71da8ad 100644 --- a/AliyunOSSiOSTests/OSSConfigurationTest.m +++ b/AliyunOSSiOSTests/OSSConfigurationTest.m @@ -149,4 +149,139 @@ - (void)testCustomPathPrefixEnableWithNullObject { }] waitUntilFinished]; } +- (void)testAPI_verifyStrict +{ + NSURL * fileURL = [[NSBundle mainBundle] URLForResource:@"hasky" withExtension:@"jpeg"]; + NSString *objectKey = @"?测\r试-中.~,+\"'*&¥#@%!(文)+字符|?/.zip"; + NSString *bucketName = [NSString stringWithFormat:@"verifystrict-%ld", @([[NSDate date] timeIntervalSince1970]).integerValue]; + + OSSClientConfiguration *config = [OSSClientConfiguration new]; + OSSAuthCredentialProvider *authProv = [[OSSAuthCredentialProvider alloc] initWithAuthServerUrl:OSS_STSTOKEN_URL]; + OSSClient *client = [[OSSClient alloc] initWithEndpoint:OSS_ENDPOINT + credentialProvider:authProv + clientConfiguration:config]; + XCTAssertTrue(config.isVerifyObjectStrictEnable); + + OSSCreateBucketRequest *createBucket = [OSSCreateBucketRequest new]; + createBucket.bucketName = bucketName; + [[client createBucket:createBucket] waitUntilFinished]; + + OSSPutObjectRequest * putRequest = [OSSPutObjectRequest new]; + putRequest.bucketName = bucketName; + putRequest.objectKey = objectKey; + putRequest.uploadingFileURL = fileURL; + OSSTask *task = [client putObject:putRequest]; + [task waitUntilFinished]; + + XCTAssertNil(task.error); + + OSSGetObjectRequest * request = [OSSGetObjectRequest new]; + request.bucketName = bucketName; + request.objectKey = objectKey; + task = [client getObject:request]; + [task waitUntilFinished]; + + XCTAssertNil(task.error); + + config = [OSSClientConfiguration new]; + config.isVerifyObjectStrictEnable = NO; + client = [[OSSClient alloc] initWithEndpoint:OSS_ENDPOINT + credentialProvider:authProv + clientConfiguration:config]; + XCTAssertFalse(config.isVerifyObjectStrictEnable); + + putRequest = [OSSPutObjectRequest new]; + putRequest.bucketName = bucketName; + putRequest.objectKey = objectKey; + putRequest.uploadingFileURL = fileURL; + task = [client putObject:putRequest]; + [task waitUntilFinished]; + + XCTAssertNil(task.error); + + request = [OSSGetObjectRequest new]; + request.bucketName = bucketName; + request.objectKey = objectKey; + task = [client getObject:request]; + [task waitUntilFinished]; + + XCTAssertNil(task.error); +} + +- (void)testAPI_verifyStrictWithPresign { + OSSClientConfiguration *config = [OSSClientConfiguration new]; + OSSAuthCredentialProvider *authProv = [[OSSAuthCredentialProvider alloc] initWithAuthServerUrl:OSS_STSTOKEN_URL]; + OSSClient *client = [[OSSClient alloc] initWithEndpoint:OSS_ENDPOINT + credentialProvider:authProv + clientConfiguration:config]; + XCTAssertTrue(config.isVerifyObjectStrictEnable); + + NSString *bucketName = @"verifyStrictWithPresign"; + NSTimeInterval expiration = 60; + NSString *objectKey = @"123"; + OSSTask *task = [client presignConstrainURLWithBucketName:bucketName + withObjectKey:objectKey + withExpirationInterval:expiration]; + XCTAssertNil(task.error); + task = [client presignPublicURLWithBucketName:bucketName + withObjectKey:objectKey]; + XCTAssertNil(task.error); + + objectKey = @"?123"; + task = [client presignConstrainURLWithBucketName:bucketName + withObjectKey:objectKey + withExpirationInterval:expiration]; + XCTAssertNotNil(task.error); + XCTAssertTrue([task.error.userInfo[@"ErrorMessage"] isEqualToString:@"Object key invalid"]); + task = [client presignPublicURLWithBucketName:bucketName + withObjectKey:objectKey]; + XCTAssertNotNil(task.error); + XCTAssertTrue([task.error.userInfo[@"ErrorMessage"] isEqualToString:@"Object key invalid"]); + + objectKey = @"?"; + task = [client presignConstrainURLWithBucketName:bucketName + withObjectKey:objectKey + withExpirationInterval:expiration]; + XCTAssertNotNil(task.error); + XCTAssertTrue([task.error.userInfo[@"ErrorMessage"] isEqualToString:@"Object key invalid"]); + task = [client presignPublicURLWithBucketName:bucketName + withObjectKey:objectKey]; + XCTAssertNotNil(task.error); + XCTAssertTrue([task.error.userInfo[@"ErrorMessage"] isEqualToString:@"Object key invalid"]); + + + config = [OSSClientConfiguration new]; + config.isVerifyObjectStrictEnable = false; + client = [[OSSClient alloc] initWithEndpoint:OSS_ENDPOINT + credentialProvider:authProv + clientConfiguration:config]; + XCTAssertFalse(config.isVerifyObjectStrictEnable); + objectKey = @"123"; + task = [client presignConstrainURLWithBucketName:bucketName + withObjectKey:objectKey + withExpirationInterval:expiration]; + XCTAssertNil(task.error); + task = [client presignPublicURLWithBucketName:bucketName + withObjectKey:objectKey]; + XCTAssertNil(task.error); + + objectKey = @"?123"; + task = [client presignConstrainURLWithBucketName:bucketName + withObjectKey:objectKey + withExpirationInterval:expiration]; + XCTAssertNil(task.error); + task = [client presignPublicURLWithBucketName:bucketName + withObjectKey:objectKey]; + XCTAssertNil(task.error); + + objectKey = @"?"; + task = [client presignConstrainURLWithBucketName:bucketName + withObjectKey:objectKey + withExpirationInterval:expiration]; + XCTAssertNil(task.error); + task = [client presignPublicURLWithBucketName:bucketName + withObjectKey:objectKey]; + XCTAssertNil(task.error); +} + @end From 7e69f31289e724ba598e7339af79db6df8afa14b Mon Sep 17 00:00:00 2001 From: ws Date: Thu, 7 Dec 2023 19:01:01 +0800 Subject: [PATCH 2/2] Modify the information of version 2.10.19 --- AliyunOSSSDK/OSSDefine.h | 2 +- AliyunOSSiOS.podspec | 2 +- CHANGLOG.txt | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/AliyunOSSSDK/OSSDefine.h b/AliyunOSSSDK/OSSDefine.h index b69c980..487151d 100644 --- a/AliyunOSSSDK/OSSDefine.h +++ b/AliyunOSSSDK/OSSDefine.h @@ -16,7 +16,7 @@ #elif TARGET_OS_OSX #define OSSUAPrefix @"aliyun-sdk-mac" #endif -#define OSSSDKVersion @"2.10.18" +#define OSSSDKVersion @"2.10.19" #define OSSListBucketResultXMLTOKEN @"ListBucketResult" #define OSSNameXMLTOKEN @"Name" diff --git a/AliyunOSSiOS.podspec b/AliyunOSSiOS.podspec index 19686f6..fc0258a 100644 --- a/AliyunOSSiOS.podspec +++ b/AliyunOSSiOS.podspec @@ -2,7 +2,7 @@ Pod::Spec.new do |s| s.name = "AliyunOSSiOS" - s.version = "2.10.18" + s.version = "2.10.19" s.summary = "An iOS SDK for Aliyun Object Storage Service" diff --git a/CHANGLOG.txt b/CHANGLOG.txt index d5f6cb7..8d0a66c 100755 --- a/CHANGLOG.txt +++ b/CHANGLOG.txt @@ -15,6 +15,10 @@ pod dependency: pod 'AliyunOSSiOS' Update Logs: +2023/12/7 +- release 2.10.19 +1.support to verify object name strictly. + 2023/5/29 - release 2.10.18 1.Perform MD5 conversion on breakpoint continuation file names