Recognise send_file as a FileSystemAccess

This method is available in ActionController actions, and sends the file
at the given path to the client.
This commit is contained in:
Harry Maclean
2022-09-28 12:14:22 +13:00
parent 82bbe67267
commit 24a10aa5ff
3 changed files with 26 additions and 0 deletions

View File

@@ -357,3 +357,15 @@ private class ActionControllerProtectFromForgeryCall extends CsrfProtectionSetti
if this.getWithValueText() = "exception" then result = true else result = false
}
}
/**
* A call to `send_file`, which sends the file at the given path to the client.
*/
private class SendFile extends FileSystemAccess::Range, DataFlow::CallNode {
SendFile() {
this.asExpr().getExpr() instanceof ActionControllerContextCall and
this.getMethodName() = "send_file"
}
override DataFlow::Node getAPathArgument() { result = this.getArgument(0) }
}

View File

@@ -36,6 +36,9 @@ edges
| tainted_path.rb:59:12:59:53 | call to new : | tainted_path.rb:60:26:60:29 | path |
| tainted_path.rb:59:40:59:45 | call to params : | tainted_path.rb:59:40:59:52 | ...[...] : |
| tainted_path.rb:59:40:59:52 | ...[...] : | tainted_path.rb:59:12:59:53 | call to new : |
| tainted_path.rb:71:12:71:53 | call to new : | tainted_path.rb:72:15:72:18 | path |
| tainted_path.rb:71:40:71:45 | call to params : | tainted_path.rb:71:40:71:52 | ...[...] : |
| tainted_path.rb:71:40:71:52 | ...[...] : | tainted_path.rb:71:12:71:53 | call to new : |
nodes
| ArchiveApiPathTraversal.rb:5:26:5:31 | call to params : | semmle.label | call to params : |
| ArchiveApiPathTraversal.rb:5:26:5:42 | ...[...] : | semmle.label | ...[...] : |
@@ -86,6 +89,10 @@ nodes
| tainted_path.rb:59:40:59:45 | call to params : | semmle.label | call to params : |
| tainted_path.rb:59:40:59:52 | ...[...] : | semmle.label | ...[...] : |
| tainted_path.rb:60:26:60:29 | path | semmle.label | path |
| tainted_path.rb:71:12:71:53 | call to new : | semmle.label | call to new : |
| tainted_path.rb:71:40:71:45 | call to params : | semmle.label | call to params : |
| tainted_path.rb:71:40:71:52 | ...[...] : | semmle.label | ...[...] : |
| tainted_path.rb:72:15:72:18 | path | semmle.label | path |
subpaths
#select
| ArchiveApiPathTraversal.rb:59:21:59:36 | destination_file | ArchiveApiPathTraversal.rb:5:26:5:31 | call to params : | ArchiveApiPathTraversal.rb:59:21:59:36 | destination_file | This path depends on a $@. | ArchiveApiPathTraversal.rb:5:26:5:31 | call to params | user-provided value |
@@ -100,3 +107,4 @@ subpaths
| tainted_path.rb:41:26:41:29 | path | tainted_path.rb:40:26:40:31 | call to params : | tainted_path.rb:41:26:41:29 | path | This path depends on a $@. | tainted_path.rb:40:26:40:31 | call to params | user-provided value |
| tainted_path.rb:48:26:48:29 | path | tainted_path.rb:47:43:47:48 | call to params : | tainted_path.rb:48:26:48:29 | path | This path depends on a $@. | tainted_path.rb:47:43:47:48 | call to params | user-provided value |
| tainted_path.rb:60:26:60:29 | path | tainted_path.rb:59:40:59:45 | call to params : | tainted_path.rb:60:26:60:29 | path | This path depends on a $@. | tainted_path.rb:59:40:59:45 | call to params | user-provided value |
| tainted_path.rb:72:15:72:18 | path | tainted_path.rb:71:40:71:45 | call to params : | tainted_path.rb:72:15:72:18 | path | This path depends on a $@. | tainted_path.rb:71:40:71:45 | call to params | user-provided value |

View File

@@ -65,4 +65,10 @@ class FooController < ActionController::Base
path = ActiveStorage::Filename.new(params[:path]).sanitized
@content = File.read path
end
# BAD
def route11
path = ActiveStorage::Filename.new(params[:path])
send_file path
end
end