Skip to content

Commit 87745c0

Browse files
committed
Use GCDWebServerNormalizePath() on all relative paths passed to GCDWebServer
1 parent ec800b4 commit 87745c0

3 files changed

Lines changed: 30 additions & 57 deletions

File tree

GCDWebDAVServer/GCDWebDAVServer.m

Lines changed: 16 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ @implementation GCDWebDAVServer
7777

7878
- (instancetype)initWithUploadDirectory:(NSString*)path {
7979
if ((self = [super init])) {
80-
_uploadDirectory = [[path stringByStandardizingPath] copy];
80+
_uploadDirectory = [path copy];
8181
GCDWebDAVServer* __unsafe_unretained server = self;
8282

8383
// 9.1 PROPFIND method
@@ -157,11 +157,6 @@ - (instancetype)initWithUploadDirectory:(NSString*)path {
157157

158158
@implementation GCDWebDAVServer (Methods)
159159

160-
// Must match implementation in GCDWebUploader
161-
- (BOOL)_checkSandboxedPath:(NSString*)path {
162-
return [[path stringByStandardizingPath] hasPrefix:_uploadDirectory];
163-
}
164-
165160
- (BOOL)_checkFileExtension:(NSString*)fileName {
166161
if (_allowedFileExtensions && ![_allowedFileExtensions containsObject:[[fileName pathExtension] lowercaseString]]) {
167162
return NO;
@@ -186,9 +181,9 @@ - (GCDWebServerResponse*)performOPTIONS:(GCDWebServerRequest*)request {
186181

187182
- (GCDWebServerResponse*)performGET:(GCDWebServerRequest*)request {
188183
NSString* relativePath = request.path;
189-
NSString* absolutePath = [_uploadDirectory stringByAppendingPathComponent:relativePath];
184+
NSString* absolutePath = [_uploadDirectory stringByAppendingPathComponent:GCDWebServerNormalizePath(relativePath)];
190185
BOOL isDirectory = NO;
191-
if (![self _checkSandboxedPath:absolutePath] || ![[NSFileManager defaultManager] fileExistsAtPath:absolutePath isDirectory:&isDirectory]) {
186+
if (![[NSFileManager defaultManager] fileExistsAtPath:absolutePath isDirectory:&isDirectory]) {
192187
return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_NotFound message:@"\"%@\" does not exist", relativePath];
193188
}
194189

@@ -221,10 +216,7 @@ - (GCDWebServerResponse*)performPUT:(GCDWebServerFileRequest*)request {
221216
}
222217

223218
NSString* relativePath = request.path;
224-
NSString* absolutePath = [_uploadDirectory stringByAppendingPathComponent:relativePath];
225-
if (![self _checkSandboxedPath:absolutePath]) {
226-
return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_NotFound message:@"\"%@\" does not exist", relativePath];
227-
}
219+
NSString* absolutePath = [_uploadDirectory stringByAppendingPathComponent:GCDWebServerNormalizePath(relativePath)];
228220
BOOL isDirectory;
229221
if (![[NSFileManager defaultManager] fileExistsAtPath:[absolutePath stringByDeletingLastPathComponent] isDirectory:&isDirectory] || !isDirectory) {
230222
return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_Conflict message:@"Missing intermediate collection(s) for \"%@\"", relativePath];
@@ -265,9 +257,9 @@ - (GCDWebServerResponse*)performDELETE:(GCDWebServerRequest*)request {
265257
}
266258

267259
NSString* relativePath = request.path;
268-
NSString* absolutePath = [_uploadDirectory stringByAppendingPathComponent:relativePath];
260+
NSString* absolutePath = [_uploadDirectory stringByAppendingPathComponent:GCDWebServerNormalizePath(relativePath)];
269261
BOOL isDirectory = NO;
270-
if (![self _checkSandboxedPath:absolutePath] || ![[NSFileManager defaultManager] fileExistsAtPath:absolutePath isDirectory:&isDirectory]) {
262+
if (![[NSFileManager defaultManager] fileExistsAtPath:absolutePath isDirectory:&isDirectory]) {
271263
return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_NotFound message:@"\"%@\" does not exist", relativePath];
272264
}
273265

@@ -299,10 +291,7 @@ - (GCDWebServerResponse*)performMKCOL:(GCDWebServerDataRequest*)request {
299291
}
300292

301293
NSString* relativePath = request.path;
302-
NSString* absolutePath = [_uploadDirectory stringByAppendingPathComponent:relativePath];
303-
if (![self _checkSandboxedPath:absolutePath]) {
304-
return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_NotFound message:@"\"%@\" does not exist", relativePath];
305-
}
294+
NSString* absolutePath = [_uploadDirectory stringByAppendingPathComponent:GCDWebServerNormalizePath(relativePath)];
306295
BOOL isDirectory;
307296
if (![[NSFileManager defaultManager] fileExistsAtPath:[absolutePath stringByDeletingLastPathComponent] isDirectory:&isDirectory] || !isDirectory) {
308297
return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_Conflict message:@"Missing intermediate collection(s) for \"%@\"", relativePath];
@@ -348,10 +337,7 @@ - (GCDWebServerResponse*)performCOPY:(GCDWebServerRequest*)request isMove:(BOOL)
348337
}
349338

350339
NSString* srcRelativePath = request.path;
351-
NSString* srcAbsolutePath = [_uploadDirectory stringByAppendingPathComponent:srcRelativePath];
352-
if (![self _checkSandboxedPath:srcAbsolutePath]) {
353-
return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_NotFound message:@"\"%@\" does not exist", srcRelativePath];
354-
}
340+
NSString* srcAbsolutePath = [_uploadDirectory stringByAppendingPathComponent:GCDWebServerNormalizePath(srcRelativePath)];
355341

356342
NSString* dstRelativePath = [request.headers objectForKey:@"Destination"];
357343
NSRange range = [dstRelativePath rangeOfString:(NSString*)[request.headers objectForKey:@"Host"]];
@@ -362,8 +348,8 @@ - (GCDWebServerResponse*)performCOPY:(GCDWebServerRequest*)request isMove:(BOOL)
362348
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
363349
dstRelativePath = [[dstRelativePath substringFromIndex:(range.location + range.length)] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
364350
#pragma clang diagnostic pop
365-
NSString* dstAbsolutePath = [_uploadDirectory stringByAppendingPathComponent:dstRelativePath];
366-
if (![self _checkSandboxedPath:dstAbsolutePath]) {
351+
NSString* dstAbsolutePath = [_uploadDirectory stringByAppendingPathComponent:GCDWebServerNormalizePath(dstRelativePath)];
352+
if (!dstAbsolutePath) {
367353
return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_NotFound message:@"\"%@\" does not exist", srcRelativePath];
368354
}
369355

@@ -532,9 +518,9 @@ - (GCDWebServerResponse*)performPROPFIND:(GCDWebServerDataRequest*)request {
532518
}
533519

534520
NSString* relativePath = request.path;
535-
NSString* absolutePath = [_uploadDirectory stringByAppendingPathComponent:relativePath];
521+
NSString* absolutePath = [_uploadDirectory stringByAppendingPathComponent:GCDWebServerNormalizePath(relativePath)];
536522
BOOL isDirectory = NO;
537-
if (![self _checkSandboxedPath:absolutePath] || ![[NSFileManager defaultManager] fileExistsAtPath:absolutePath isDirectory:&isDirectory]) {
523+
if (![[NSFileManager defaultManager] fileExistsAtPath:absolutePath isDirectory:&isDirectory]) {
538524
return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_NotFound message:@"\"%@\" does not exist", relativePath];
539525
}
540526

@@ -582,9 +568,9 @@ - (GCDWebServerResponse*)performLOCK:(GCDWebServerDataRequest*)request {
582568
}
583569

584570
NSString* relativePath = request.path;
585-
NSString* absolutePath = [_uploadDirectory stringByAppendingPathComponent:relativePath];
571+
NSString* absolutePath = [_uploadDirectory stringByAppendingPathComponent:GCDWebServerNormalizePath(relativePath)];
586572
BOOL isDirectory = NO;
587-
if (![self _checkSandboxedPath:absolutePath] || ![[NSFileManager defaultManager] fileExistsAtPath:absolutePath isDirectory:&isDirectory]) {
573+
if (![[NSFileManager defaultManager] fileExistsAtPath:absolutePath isDirectory:&isDirectory]) {
588574
return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_NotFound message:@"\"%@\" does not exist", relativePath];
589575
}
590576

@@ -679,9 +665,9 @@ - (GCDWebServerResponse*)performUNLOCK:(GCDWebServerRequest*)request {
679665
}
680666

681667
NSString* relativePath = request.path;
682-
NSString* absolutePath = [_uploadDirectory stringByAppendingPathComponent:relativePath];
668+
NSString* absolutePath = [_uploadDirectory stringByAppendingPathComponent:GCDWebServerNormalizePath(relativePath)];
683669
BOOL isDirectory = NO;
684-
if (![self _checkSandboxedPath:absolutePath] || ![[NSFileManager defaultManager] fileExistsAtPath:absolutePath isDirectory:&isDirectory]) {
670+
if (![[NSFileManager defaultManager] fileExistsAtPath:absolutePath isDirectory:&isDirectory]) {
685671
return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_NotFound message:@"\"%@\" does not exist", relativePath];
686672
}
687673

GCDWebServer/Core/GCDWebServer.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1026,7 +1026,7 @@ - (void)addGETHandlerForBasePath:(NSString*)basePath directoryPath:(NSString*)di
10261026
}
10271027
processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) {
10281028
GCDWebServerResponse* response = nil;
1029-
NSString* filePath = [directoryPath stringByAppendingPathComponent:[request.path substringFromIndex:basePath.length]];
1029+
NSString* filePath = [directoryPath stringByAppendingPathComponent:GCDWebServerNormalizePath([request.path substringFromIndex:basePath.length])];
10301030
NSString* fileType = [[[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:NULL] fileType];
10311031
if (fileType) {
10321032
if ([fileType isEqualToString:NSFileTypeDirectory]) {

GCDWebUploader/GCDWebUploader.m

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#endif
3838

3939
#import "GCDWebUploader.h"
40+
#import "GCDWebServerFunctions.h"
4041

4142
#import "GCDWebServerDataRequest.h"
4243
#import "GCDWebServerMultiPartFormRequest.h"
@@ -73,7 +74,7 @@ - (instancetype)initWithUploadDirectory:(NSString*)path {
7374
if (siteBundle == nil) {
7475
return nil;
7576
}
76-
_uploadDirectory = [[path stringByStandardizingPath] copy];
77+
_uploadDirectory = [path copy];
7778
GCDWebUploader* __unsafe_unretained server = self;
7879

7980
// Resource files
@@ -192,11 +193,6 @@ - (instancetype)initWithUploadDirectory:(NSString*)path {
192193

193194
@implementation GCDWebUploader (Methods)
194195

195-
// Must match implementation in GCDWebDAVServer
196-
- (BOOL)_checkSandboxedPath:(NSString*)path {
197-
return [[path stringByStandardizingPath] hasPrefix:_uploadDirectory];
198-
}
199-
200196
- (BOOL)_checkFileExtension:(NSString*)fileName {
201197
if (_allowedFileExtensions && ![_allowedFileExtensions containsObject:[[fileName pathExtension] lowercaseString]]) {
202198
return NO;
@@ -224,9 +220,9 @@ - (NSString*)_uniquePathForPath:(NSString*)path {
224220

225221
- (GCDWebServerResponse*)listDirectory:(GCDWebServerRequest*)request {
226222
NSString* relativePath = [[request query] objectForKey:@"path"];
227-
NSString* absolutePath = [_uploadDirectory stringByAppendingPathComponent:relativePath];
223+
NSString* absolutePath = [_uploadDirectory stringByAppendingPathComponent:GCDWebServerNormalizePath(relativePath)];
228224
BOOL isDirectory = NO;
229-
if (![self _checkSandboxedPath:absolutePath] || ![[NSFileManager defaultManager] fileExistsAtPath:absolutePath isDirectory:&isDirectory]) {
225+
if (!absolutePath || ![[NSFileManager defaultManager] fileExistsAtPath:absolutePath isDirectory:&isDirectory]) {
230226
return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_NotFound message:@"\"%@\" does not exist", relativePath];
231227
}
232228
if (!isDirectory) {
@@ -268,9 +264,9 @@ - (GCDWebServerResponse*)listDirectory:(GCDWebServerRequest*)request {
268264

269265
- (GCDWebServerResponse*)downloadFile:(GCDWebServerRequest*)request {
270266
NSString* relativePath = [[request query] objectForKey:@"path"];
271-
NSString* absolutePath = [_uploadDirectory stringByAppendingPathComponent:relativePath];
267+
NSString* absolutePath = [_uploadDirectory stringByAppendingPathComponent:GCDWebServerNormalizePath(relativePath)];
272268
BOOL isDirectory = NO;
273-
if (![self _checkSandboxedPath:absolutePath] || ![[NSFileManager defaultManager] fileExistsAtPath:absolutePath isDirectory:&isDirectory]) {
269+
if (![[NSFileManager defaultManager] fileExistsAtPath:absolutePath isDirectory:&isDirectory]) {
274270
return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_NotFound message:@"\"%@\" does not exist", relativePath];
275271
}
276272
if (isDirectory) {
@@ -299,10 +295,7 @@ - (GCDWebServerResponse*)uploadFile:(GCDWebServerMultiPartFormRequest*)request {
299295
return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_Forbidden message:@"Uploaded file name \"%@\" is not allowed", file.fileName];
300296
}
301297
NSString* relativePath = [[request firstArgumentForControlName:@"path"] string];
302-
NSString* absolutePath = [self _uniquePathForPath:[[_uploadDirectory stringByAppendingPathComponent:relativePath] stringByAppendingPathComponent:file.fileName]];
303-
if (![self _checkSandboxedPath:absolutePath]) {
304-
return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_NotFound message:@"\"%@\" does not exist", relativePath];
305-
}
298+
NSString* absolutePath = [self _uniquePathForPath:[[_uploadDirectory stringByAppendingPathComponent:GCDWebServerNormalizePath(relativePath)] stringByAppendingPathComponent:file.fileName]];
306299

307300
if (![self shouldUploadFileAtPath:absolutePath withTemporaryFile:file.temporaryPath]) {
308301
return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_Forbidden message:@"Uploading file \"%@\" to \"%@\" is not permitted", file.fileName, relativePath];
@@ -323,17 +316,14 @@ - (GCDWebServerResponse*)uploadFile:(GCDWebServerMultiPartFormRequest*)request {
323316

324317
- (GCDWebServerResponse*)moveItem:(GCDWebServerURLEncodedFormRequest*)request {
325318
NSString* oldRelativePath = [request.arguments objectForKey:@"oldPath"];
326-
NSString* oldAbsolutePath = [_uploadDirectory stringByAppendingPathComponent:oldRelativePath];
319+
NSString* oldAbsolutePath = [_uploadDirectory stringByAppendingPathComponent:GCDWebServerNormalizePath(oldRelativePath)];
327320
BOOL isDirectory = NO;
328-
if (![self _checkSandboxedPath:oldAbsolutePath] || ![[NSFileManager defaultManager] fileExistsAtPath:oldAbsolutePath isDirectory:&isDirectory]) {
321+
if (![[NSFileManager defaultManager] fileExistsAtPath:oldAbsolutePath isDirectory:&isDirectory]) {
329322
return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_NotFound message:@"\"%@\" does not exist", oldRelativePath];
330323
}
331324

332325
NSString* newRelativePath = [request.arguments objectForKey:@"newPath"];
333-
NSString* newAbsolutePath = [self _uniquePathForPath:[_uploadDirectory stringByAppendingPathComponent:newRelativePath]];
334-
if (![self _checkSandboxedPath:newAbsolutePath]) {
335-
return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_NotFound message:@"\"%@\" does not exist", newRelativePath];
336-
}
326+
NSString* newAbsolutePath = [self _uniquePathForPath:[_uploadDirectory stringByAppendingPathComponent:GCDWebServerNormalizePath(newRelativePath)]];
337327

338328
NSString* itemName = [newAbsolutePath lastPathComponent];
339329
if ((!_allowHiddenItems && [itemName hasPrefix:@"."]) || (!isDirectory && ![self _checkFileExtension:itemName])) {
@@ -359,9 +349,9 @@ - (GCDWebServerResponse*)moveItem:(GCDWebServerURLEncodedFormRequest*)request {
359349

360350
- (GCDWebServerResponse*)deleteItem:(GCDWebServerURLEncodedFormRequest*)request {
361351
NSString* relativePath = [request.arguments objectForKey:@"path"];
362-
NSString* absolutePath = [_uploadDirectory stringByAppendingPathComponent:relativePath];
352+
NSString* absolutePath = [_uploadDirectory stringByAppendingPathComponent:GCDWebServerNormalizePath(relativePath)];
363353
BOOL isDirectory = NO;
364-
if (![self _checkSandboxedPath:absolutePath] || ![[NSFileManager defaultManager] fileExistsAtPath:absolutePath isDirectory:&isDirectory]) {
354+
if (![[NSFileManager defaultManager] fileExistsAtPath:absolutePath isDirectory:&isDirectory]) {
365355
return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_NotFound message:@"\"%@\" does not exist", relativePath];
366356
}
367357

@@ -389,10 +379,7 @@ - (GCDWebServerResponse*)deleteItem:(GCDWebServerURLEncodedFormRequest*)request
389379

390380
- (GCDWebServerResponse*)createDirectory:(GCDWebServerURLEncodedFormRequest*)request {
391381
NSString* relativePath = [request.arguments objectForKey:@"path"];
392-
NSString* absolutePath = [self _uniquePathForPath:[_uploadDirectory stringByAppendingPathComponent:relativePath]];
393-
if (![self _checkSandboxedPath:absolutePath]) {
394-
return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_NotFound message:@"\"%@\" does not exist", relativePath];
395-
}
382+
NSString* absolutePath = [self _uniquePathForPath:[_uploadDirectory stringByAppendingPathComponent:GCDWebServerNormalizePath(relativePath)]];
396383

397384
NSString* directoryName = [absolutePath lastPathComponent];
398385
if (!_allowHiddenItems && [directoryName hasPrefix:@"."]) {

0 commit comments

Comments
 (0)