Applying equivalent patch for 830cc8df3ca6a564b7675672279c7715a56b2718, addressing a security vulnerability caused by known multipart form boundaries

This commit is contained in:
Mattt Thompson 2014-04-15 13:15:30 -07:00
parent 55ef458688
commit b3d44e2fc3

View file

@ -759,20 +759,22 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) {
#pragma mark - #pragma mark -
static NSString * const kAFMultipartFormBoundary = @"Boundary+0xAbCdEfGbOuNdArY"; static NSString * AFCreateMultipartFormBoundary() {
return [NSString stringWithFormat:@"Boundary+%08X%08X", arc4random(), arc4random()];
}
static NSString * const kAFMultipartFormCRLF = @"\r\n"; static NSString * const kAFMultipartFormCRLF = @"\r\n";
static inline NSString * AFMultipartFormInitialBoundary() { static inline NSString * AFMultipartFormInitialBoundary(NSString *boundary) {
return [NSString stringWithFormat:@"--%@%@", kAFMultipartFormBoundary, kAFMultipartFormCRLF]; return [NSString stringWithFormat:@"--%@%@", boundary, kAFMultipartFormCRLF];
} }
static inline NSString * AFMultipartFormEncapsulationBoundary() { static inline NSString * AFMultipartFormEncapsulationBoundary(NSString *boundary) {
return [NSString stringWithFormat:@"%@--%@%@", kAFMultipartFormCRLF, kAFMultipartFormBoundary, kAFMultipartFormCRLF]; return [NSString stringWithFormat:@"%@--%@%@", kAFMultipartFormCRLF, boundary, kAFMultipartFormCRLF];
} }
static inline NSString * AFMultipartFormFinalBoundary() { static inline NSString * AFMultipartFormFinalBoundary(NSString *boundary) {
return [NSString stringWithFormat:@"%@--%@--%@", kAFMultipartFormCRLF, kAFMultipartFormBoundary, kAFMultipartFormCRLF]; return [NSString stringWithFormat:@"%@--%@--%@", kAFMultipartFormCRLF, boundary, kAFMultipartFormCRLF];
} }
static inline NSString * AFContentTypeForPathExtension(NSString *extension) { static inline NSString * AFContentTypeForPathExtension(NSString *extension) {
@ -799,6 +801,7 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
@property (nonatomic, assign) unsigned long long bodyContentLength; @property (nonatomic, assign) unsigned long long bodyContentLength;
@property (nonatomic, strong) NSInputStream *inputStream; @property (nonatomic, strong) NSInputStream *inputStream;
@property (nonatomic, copy) NSString *boundary;
@property (nonatomic, assign) BOOL hasInitialBoundary; @property (nonatomic, assign) BOOL hasInitialBoundary;
@property (nonatomic, assign) BOOL hasFinalBoundary; @property (nonatomic, assign) BOOL hasFinalBoundary;
@ -825,6 +828,7 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
@interface AFStreamingMultipartFormData () @interface AFStreamingMultipartFormData ()
@property (readwrite, nonatomic, copy) NSMutableURLRequest *request; @property (readwrite, nonatomic, copy) NSMutableURLRequest *request;
@property (nonatomic, copy) NSString *boundary;
@property (readwrite, nonatomic, strong) AFMultipartBodyStream *bodyStream; @property (readwrite, nonatomic, strong) AFMultipartBodyStream *bodyStream;
@property (readwrite, nonatomic, assign) NSStringEncoding stringEncoding; @property (readwrite, nonatomic, assign) NSStringEncoding stringEncoding;
@end @end
@ -844,6 +848,7 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
self.request = urlRequest; self.request = urlRequest;
self.stringEncoding = encoding; self.stringEncoding = encoding;
self.boundary = AFCreateMultipartFormBoundary();
self.bodyStream = [[AFMultipartBodyStream alloc] initWithStringEncoding:encoding]; self.bodyStream = [[AFMultipartBodyStream alloc] initWithStringEncoding:encoding];
return self; return self;
@ -896,6 +901,7 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
AFHTTPBodyPart *bodyPart = [[AFHTTPBodyPart alloc] init]; AFHTTPBodyPart *bodyPart = [[AFHTTPBodyPart alloc] init];
bodyPart.stringEncoding = self.stringEncoding; bodyPart.stringEncoding = self.stringEncoding;
bodyPart.headers = mutableHeaders; bodyPart.headers = mutableHeaders;
bodyPart.boundary = self.boundary;
bodyPart.body = fileURL; bodyPart.body = fileURL;
NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[fileURL path] error:nil]; NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[fileURL path] error:nil];
@ -925,6 +931,7 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
AFHTTPBodyPart *bodyPart = [[AFHTTPBodyPart alloc] init]; AFHTTPBodyPart *bodyPart = [[AFHTTPBodyPart alloc] init];
bodyPart.stringEncoding = self.stringEncoding; bodyPart.stringEncoding = self.stringEncoding;
bodyPart.headers = mutableHeaders; bodyPart.headers = mutableHeaders;
bodyPart.boundary = self.boundary;
bodyPart.body = inputStream; bodyPart.body = inputStream;
bodyPart.bodyContentLength = length; bodyPart.bodyContentLength = length;
@ -967,6 +974,7 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
AFHTTPBodyPart *bodyPart = [[AFHTTPBodyPart alloc] init]; AFHTTPBodyPart *bodyPart = [[AFHTTPBodyPart alloc] init];
bodyPart.stringEncoding = self.stringEncoding; bodyPart.stringEncoding = self.stringEncoding;
bodyPart.headers = headers; bodyPart.headers = headers;
bodyPart.boundary = self.boundary;
bodyPart.bodyContentLength = [body length]; bodyPart.bodyContentLength = [body length];
bodyPart.body = body; bodyPart.body = body;
@ -988,7 +996,7 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
// Reset the initial and final boundaries to ensure correct Content-Length // Reset the initial and final boundaries to ensure correct Content-Length
[self.bodyStream setInitialAndFinalBoundaries]; [self.bodyStream setInitialAndFinalBoundaries];
[self.request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", kAFMultipartFormBoundary] forHTTPHeaderField:@"Content-Type"]; [self.request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", self.boundary] forHTTPHeaderField:@"Content-Type"];
[self.request setValue:[NSString stringWithFormat:@"%llu", [self.bodyStream contentLength]] forHTTPHeaderField:@"Content-Length"]; [self.request setValue:[NSString stringWithFormat:@"%llu", [self.bodyStream contentLength]] forHTTPHeaderField:@"Content-Length"];
[self.request setHTTPBodyStream:self.bodyStream]; [self.request setHTTPBodyStream:self.bodyStream];
@ -1252,7 +1260,7 @@ typedef enum {
- (unsigned long long)contentLength { - (unsigned long long)contentLength {
unsigned long long length = 0; unsigned long long length = 0;
NSData *encapsulationBoundaryData = [([self hasInitialBoundary] ? AFMultipartFormInitialBoundary() : AFMultipartFormEncapsulationBoundary()) dataUsingEncoding:self.stringEncoding]; NSData *encapsulationBoundaryData = [([self hasInitialBoundary] ? AFMultipartFormInitialBoundary(self.boundary) : AFMultipartFormEncapsulationBoundary(self.boundary)) dataUsingEncoding:self.stringEncoding];
length += [encapsulationBoundaryData length]; length += [encapsulationBoundaryData length];
NSData *headersData = [[self stringForHeaders] dataUsingEncoding:self.stringEncoding]; NSData *headersData = [[self stringForHeaders] dataUsingEncoding:self.stringEncoding];
@ -1260,7 +1268,7 @@ typedef enum {
length += _bodyContentLength; length += _bodyContentLength;
NSData *closingBoundaryData = ([self hasFinalBoundary] ? [AFMultipartFormFinalBoundary() dataUsingEncoding:self.stringEncoding] : [NSData data]); NSData *closingBoundaryData = ([self hasFinalBoundary] ? [AFMultipartFormFinalBoundary(self.boundary) dataUsingEncoding:self.stringEncoding] : [NSData data]);
length += [closingBoundaryData length]; length += [closingBoundaryData length];
return length; return length;
@ -1296,7 +1304,7 @@ typedef enum {
NSUInteger totalNumberOfBytesRead = 0; NSUInteger totalNumberOfBytesRead = 0;
if (_phase == AFEncapsulationBoundaryPhase) { if (_phase == AFEncapsulationBoundaryPhase) {
NSData *encapsulationBoundaryData = [([self hasInitialBoundary] ? AFMultipartFormInitialBoundary() : AFMultipartFormEncapsulationBoundary()) dataUsingEncoding:self.stringEncoding]; NSData *encapsulationBoundaryData = [([self hasInitialBoundary] ? AFMultipartFormInitialBoundary(self.boundary) : AFMultipartFormEncapsulationBoundary(self.boundary)) dataUsingEncoding:self.stringEncoding];
totalNumberOfBytesRead += [self readData:encapsulationBoundaryData intoBuffer:&buffer[totalNumberOfBytesRead] maxLength:(length - (NSUInteger)totalNumberOfBytesRead)]; totalNumberOfBytesRead += [self readData:encapsulationBoundaryData intoBuffer:&buffer[totalNumberOfBytesRead] maxLength:(length - (NSUInteger)totalNumberOfBytesRead)];
} }
@ -1321,7 +1329,7 @@ typedef enum {
} }
if (_phase == AFFinalBoundaryPhase) { if (_phase == AFFinalBoundaryPhase) {
NSData *closingBoundaryData = ([self hasFinalBoundary] ? [AFMultipartFormFinalBoundary() dataUsingEncoding:self.stringEncoding] : [NSData data]); NSData *closingBoundaryData = ([self hasFinalBoundary] ? [AFMultipartFormFinalBoundary(self.boundary) dataUsingEncoding:self.stringEncoding] : [NSData data]);
totalNumberOfBytesRead += [self readData:closingBoundaryData intoBuffer:&buffer[totalNumberOfBytesRead] maxLength:(length - (NSUInteger)totalNumberOfBytesRead)]; totalNumberOfBytesRead += [self readData:closingBoundaryData intoBuffer:&buffer[totalNumberOfBytesRead] maxLength:(length - (NSUInteger)totalNumberOfBytesRead)];
} }