Skip to content

Commit 25300cb

Browse files
committed
start modelling some file access concepts
1 parent dd31473 commit 25300cb

File tree

3 files changed

+95
-0
lines changed

3 files changed

+95
-0
lines changed

ql/lib/codeql/ruby/Concepts.qll

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,46 @@ module SqlExecution {
3636
}
3737
}
3838

39+
/**
40+
* A data flow node that performs a file system access (read, write, copy, permissions, stats, etc).
41+
*/
42+
abstract class FileSystemAccess extends DataFlow::Node {
43+
/** Gets an argument to this file system access that is interpreted as a path. */
44+
abstract DataFlow::Node getAPathArgument();
45+
46+
/**
47+
* Gets an argument to this file system access that is interpreted as a root folder
48+
* in which the path arguments are constrained.
49+
*
50+
* In other words, if a root argument is provided, the underlying file access does its own
51+
* sanitization to prevent the path arguments from traversing outside the root folder.
52+
*/
53+
DataFlow::Node getRootPathArgument() { none() }
54+
55+
/**
56+
* Holds if this file system access will reject paths containing upward navigation
57+
* segments (`../`).
58+
*
59+
* `argument` should refer to the relevant path argument or root path argument.
60+
*/
61+
predicate isUpwardNavigationRejected(DataFlow::Node argument) { none() }
62+
}
63+
64+
/**
65+
* A data flow node that reads data from the file system.
66+
*/
67+
abstract class FileSystemReadAccess extends FileSystemAccess {
68+
/** Gets a node that represents data from the file system. */
69+
abstract DataFlow::Node getADataNode();
70+
}
71+
72+
73+
/**
74+
* A data flow node that contains a file name or an array of file names from the local file system.
75+
*/
76+
abstract class FileNameSource extends DataFlow::Node { }
77+
78+
3979
/**
4080
* A data-flow node that escapes meta-characters, which could be used to prevent
4181
* injection attacks.

ql/lib/codeql/ruby/Frameworks.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ private import codeql.ruby.frameworks.ActionController
66
private import codeql.ruby.frameworks.ActiveRecord
77
private import codeql.ruby.frameworks.ActionView
88
private import codeql.ruby.frameworks.StandardLibrary
9+
private import codeql.ruby.frameworks.Files
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* Provides classes for working with file system libraries.
3+
*/
4+
5+
private import ruby
6+
private import codeql.ruby.Concepts
7+
private import codeql.ruby.ApiGraphs
8+
9+
/** A permissions argument of a call to a File/FileUtils method that may modify file permissions */
10+
/*
11+
class PermissionArgument extends DataFlow::Node {
12+
private DataFlow::CallNode call;
13+
14+
PermissionArgument() {
15+
exists(string methodName |
16+
call = API::getTopLevelMember(["File", "FileUtils"]).getAMethodCall(methodName)
17+
|
18+
methodName in ["chmod", "chmod_R", "lchmod"] and this = call.getArgument(0)
19+
or
20+
methodName = "mkfifo" and this = call.getArgument(1)
21+
or
22+
methodName in ["new", "open"] and this = call.getArgument(2)
23+
or
24+
methodName in ["install", "makedirs", "mkdir", "mkdir_p", "mkpath"] and
25+
this = call.getKeywordArgument("mode")
26+
// TODO: defaults for optional args? This may depend on the umask
27+
)
28+
}
29+
30+
MethodCall getCall() { result = call.asExpr().getExpr() }
31+
}
32+
*/
33+
34+
35+
class StdLibFileNameSource extends FileNameSource {
36+
StdLibFileNameSource() {
37+
this = API::getTopLevelMember("File").getAMethodCall(["join", "path", "to_path", "readlink"])
38+
39+
}
40+
}
41+
42+
/**
43+
* Classes and predicates for modelling the `File` module from the standard
44+
* library.
45+
*/
46+
private module File {
47+
48+
class FileModuleReader extends FileSystemReadAccess, DataFlow::CallNode {
49+
FileModuleReader() {
50+
this = API::getTopLevelMember("File").getAMethodCall(["new", "open"])
51+
}
52+
}
53+
54+
}

0 commit comments

Comments
 (0)