start modelling some file access concepts

This commit is contained in:
Alex Ford
2021-09-01 18:35:09 +01:00
parent dd31473dff
commit 25300cb2b4
3 changed files with 95 additions and 0 deletions

View File

@@ -36,6 +36,46 @@ module SqlExecution {
}
}
/**
* A data flow node that performs a file system access (read, write, copy, permissions, stats, etc).
*/
abstract class FileSystemAccess extends DataFlow::Node {
/** Gets an argument to this file system access that is interpreted as a path. */
abstract DataFlow::Node getAPathArgument();
/**
* Gets an argument to this file system access that is interpreted as a root folder
* in which the path arguments are constrained.
*
* In other words, if a root argument is provided, the underlying file access does its own
* sanitization to prevent the path arguments from traversing outside the root folder.
*/
DataFlow::Node getRootPathArgument() { none() }
/**
* Holds if this file system access will reject paths containing upward navigation
* segments (`../`).
*
* `argument` should refer to the relevant path argument or root path argument.
*/
predicate isUpwardNavigationRejected(DataFlow::Node argument) { none() }
}
/**
* A data flow node that reads data from the file system.
*/
abstract class FileSystemReadAccess extends FileSystemAccess {
/** Gets a node that represents data from the file system. */
abstract DataFlow::Node getADataNode();
}
/**
* A data flow node that contains a file name or an array of file names from the local file system.
*/
abstract class FileNameSource extends DataFlow::Node { }
/**
* A data-flow node that escapes meta-characters, which could be used to prevent
* injection attacks.

View File

@@ -6,3 +6,4 @@ private import codeql.ruby.frameworks.ActionController
private import codeql.ruby.frameworks.ActiveRecord
private import codeql.ruby.frameworks.ActionView
private import codeql.ruby.frameworks.StandardLibrary
private import codeql.ruby.frameworks.Files

View File

@@ -0,0 +1,54 @@
/**
* Provides classes for working with file system libraries.
*/
private import ruby
private import codeql.ruby.Concepts
private import codeql.ruby.ApiGraphs
/** A permissions argument of a call to a File/FileUtils method that may modify file permissions */
/*
class PermissionArgument extends DataFlow::Node {
private DataFlow::CallNode call;
PermissionArgument() {
exists(string methodName |
call = API::getTopLevelMember(["File", "FileUtils"]).getAMethodCall(methodName)
|
methodName in ["chmod", "chmod_R", "lchmod"] and this = call.getArgument(0)
or
methodName = "mkfifo" and this = call.getArgument(1)
or
methodName in ["new", "open"] and this = call.getArgument(2)
or
methodName in ["install", "makedirs", "mkdir", "mkdir_p", "mkpath"] and
this = call.getKeywordArgument("mode")
// TODO: defaults for optional args? This may depend on the umask
)
}
MethodCall getCall() { result = call.asExpr().getExpr() }
}
*/
class StdLibFileNameSource extends FileNameSource {
StdLibFileNameSource() {
this = API::getTopLevelMember("File").getAMethodCall(["join", "path", "to_path", "readlink"])
}
}
/**
* Classes and predicates for modelling the `File` module from the standard
* library.
*/
private module File {
class FileModuleReader extends FileSystemReadAccess, DataFlow::CallNode {
FileModuleReader() {
this = API::getTopLevelMember("File").getAMethodCall(["new", "open"])
}
}
}