Просмотр исходного кода

Add method to sanitize full paths

For convenience, add a method to SafePath to break a path into components and verify the status of each one.

bug: overleaf/sharelatex#908
Signed-off-by: Simon Detheridge <s@sd.ai>
Simon Detheridge 8 лет назад
Родитель
Сommit
e66210d2af

+ 9 - 0
services/web/app/coffee/Features/Project/SafePath.coffee

@@ -67,6 +67,15 @@ load = () ->
 				!BADFILE_RX.test(filename) &&
 				!BADFILE_RX.test(filename) &&
 				!BLOCKEDFILE_RX.test(filename)
 				!BLOCKEDFILE_RX.test(filename)
 
 
+		isCleanPath: (path) ->
+			elements = path.split('/')
+			return false if elements[elements.length - 1].length == 0
+
+			for element in elements
+				return false if element.length > 0 && !SafePath.isCleanFilename element
+
+			return true
+
 		isAllowedLength: (pathname) ->
 		isAllowedLength: (pathname) ->
 			return pathname.length > 0 && pathname.length <= MAX_PATH
 			return pathname.length > 0 && pathname.length <= MAX_PATH
 
 

+ 56 - 3
services/web/test/unit/coffee/Project/SafePathTests.coffee

@@ -83,6 +83,59 @@ describe 'SafePath', ->
 			result = @SafePath.isCleanFilename 'foo\\bar'
 			result = @SafePath.isCleanFilename 'foo\\bar'
 			result.should.equal false
 			result.should.equal false
 
 
+	describe 'isCleanPath', ->
+		it 'should accept a valid filename "main.tex"', ->
+			result = @SafePath.isCleanPath 'main.tex'
+			result.should.equal true
+
+		it 'should accept a valid path "foo/main.tex"', ->
+			result = @SafePath.isCleanPath 'foo/main.tex'
+			result.should.equal true
+
+		it 'should accept empty path elements', ->
+			result = @SafePath.isCleanPath 'foo//main.tex'
+			result.should.equal true
+
+		it 'should not accept an empty filename', ->
+			result = @SafePath.isCleanPath 'foo/bar/'
+			result.should.equal false
+
+		it 'should accept a path that starts with a slash', ->
+			result = @SafePath.isCleanPath '/etc/passwd'
+			result.should.equal true
+
+		it 'should not accept a path that has an asterisk as the 0th element', ->
+			result = @SafePath.isCleanPath '*/foo/bar'
+			result.should.equal false
+
+		it 'should not accept a path that has an asterisk as a middle element', ->
+			result = @SafePath.isCleanPath 'foo/*/bar'
+			result.should.equal false
+
+		it 'should not accept a path that has an asterisk as the filename', ->
+			result = @SafePath.isCleanPath 'foo/bar/*'
+			result.should.equal false
+
+		it 'should not accept a path that contains an asterisk in the 0th element', ->
+			result = @SafePath.isCleanPath 'f*o/bar/baz'
+			result.should.equal false
+
+		it 'should not accept a path that contains an asterisk in a middle element', ->
+			result = @SafePath.isCleanPath 'foo/b*r/baz'
+			result.should.equal false
+
+		it 'should not accept a path that contains an asterisk in the filename', ->
+			result = @SafePath.isCleanPath 'foo/bar/b*z'
+			result.should.equal false
+
+		it 'should not accept multiple problematic elements', ->
+			result = @SafePath.isCleanPath 'f*o/b*r/b*z'
+			result.should.equal false
+
+		it 'should not accept a problematic path with an empty element', ->
+			result = @SafePath.isCleanPath 'foo//*/bar'
+			result.should.equal false
+
 	describe 'isAllowedLength', ->
 	describe 'isAllowedLength', ->
 		it 'should accept a valid path "main.tex"', ->
 		it 'should accept a valid path "main.tex"', ->
 			result = @SafePath.isAllowedLength 'main.tex'
 			result = @SafePath.isAllowedLength 'main.tex'
@@ -96,7 +149,7 @@ describe 'SafePath', ->
 		it 'should not accept an empty path', ->
 		it 'should not accept an empty path', ->
 			result = @SafePath.isAllowedLength ''
 			result = @SafePath.isAllowedLength ''
 			result.should.equal false
 			result.should.equal false
-	
+
 	describe 'clean', ->
 	describe 'clean', ->
 		it 'should not modify a valid filename', ->
 		it 'should not modify a valid filename', ->
 			result = @SafePath.clean 'main.tex'
 			result = @SafePath.clean 'main.tex'
@@ -105,7 +158,7 @@ describe 'SafePath', ->
 		it 'should replace invalid characters with _', ->
 		it 'should replace invalid characters with _', ->
 			result = @SafePath.clean 'foo/bar*/main.tex'
 			result = @SafePath.clean 'foo/bar*/main.tex'
 			result.should.equal 'foo_bar__main.tex'
 			result.should.equal 'foo_bar__main.tex'
-			
+
 		it 'should replace "." with "_"', ->
 		it 'should replace "." with "_"', ->
 			result = @SafePath.clean '.'
 			result = @SafePath.clean '.'
 			result.should.equal '_'
 			result.should.equal '_'
@@ -133,7 +186,7 @@ describe 'SafePath', ->
 		it 'should prefix javascript property names with @', ->
 		it 'should prefix javascript property names with @', ->
 			result = @SafePath.clean 'prototype'
 			result = @SafePath.clean 'prototype'
 			result.should.equal '@prototype'
 			result.should.equal '@prototype'
-		
+
 		it 'should prefix javascript property names in the prototype with @', ->
 		it 'should prefix javascript property names in the prototype with @', ->
 			result = @SafePath.clean 'hasOwnProperty'
 			result = @SafePath.clean 'hasOwnProperty'
 			result.should.equal '@hasOwnProperty'
 			result.should.equal '@hasOwnProperty'