@@ -32,20 +32,22 @@ module TarSlip {
32
32
abstract class Sanitizer extends DataFlow:: Node { }
33
33
34
34
/**
35
+ * DEPRECATED: Use `Sanitizer` instead.
36
+ *
35
37
* A sanitizer guard for "tar slip" vulnerabilities.
36
38
*/
37
- abstract class SanitizerGuard extends DataFlow:: BarrierGuard { }
39
+ abstract deprecated class SanitizerGuard extends DataFlow:: BarrierGuard { }
38
40
39
41
/**
40
- * A source of exception info , considered as a flow source.
42
+ * A call to `tarfile.open` , considered as a flow source.
41
43
*/
42
44
class TarfileOpen extends Source {
43
45
TarfileOpen ( ) {
44
46
this = API:: moduleImport ( "tarfile" ) .getMember ( "open" ) .getACall ( ) and
45
47
// If argument refers to a string object, then it's a hardcoded path and
46
48
// this tarfile is safe.
47
49
not this .( DataFlow:: CallCfgNode ) .getArg ( 0 ) .getALocalSource ( ) .asExpr ( ) instanceof StrConst and
48
- /* Ignore opens within the tarfile module itself */
50
+ // Ignore opens within the tarfile module itself
49
51
not this .getLocation ( ) .getFile ( ) .getBaseName ( ) = "tarfile.py"
50
52
}
51
53
}
@@ -110,33 +112,38 @@ module TarSlip {
110
112
}
111
113
112
114
/**
113
- * A sanitizer guard heuristic .
115
+ * Holds if `g` clears taint for `tarInfo` .
114
116
*
115
117
* The test `if <check_path>(info.name)` should clear taint for `info`,
116
118
* where `<check_path>` is any function matching `"%path"`.
117
119
* `info` is assumed to be a `TarInfo` instance.
118
120
*/
119
- class TarFileInfoSanitizer extends SanitizerGuard {
120
- ControlFlowNode tarInfo ;
121
+ predicate tarFileInfoSanitizer ( DataFlow:: GuardNode g , ControlFlowNode tarInfo , boolean branch ) {
122
+ exists ( CallNode call , AttrNode attr |
123
+ g = call and
124
+ // We must test the name of the tar info object.
125
+ attr = call .getAnArg ( ) and
126
+ attr .getName ( ) = "name" and
127
+ attr .getObject ( ) = tarInfo
128
+ |
129
+ // Assume that any test with "path" in it is a sanitizer
130
+ call .getAChild * ( ) .( AttrNode ) .getName ( ) .matches ( "%path" )
131
+ or
132
+ call .getAChild * ( ) .( NameNode ) .getId ( ) .matches ( "%path" )
133
+ ) and
134
+ branch in [ true , false ]
135
+ }
121
136
137
+ /**
138
+ * A sanitizer guard heuristic.
139
+ *
140
+ * The test `if <check_path>(info.name)` should clear taint for `info`,
141
+ * where `<check_path>` is any function matching `"%path"`.
142
+ * `info` is assumed to be a `TarInfo` instance.
143
+ */
144
+ class TarFileInfoSanitizer extends Sanitizer {
122
145
TarFileInfoSanitizer ( ) {
123
- exists ( CallNode call , AttrNode attr |
124
- this = call and
125
- // We must test the name of the tar info object.
126
- attr = call .getAnArg ( ) and
127
- attr .getName ( ) = "name" and
128
- attr .getObject ( ) = tarInfo
129
- |
130
- // Assume that any test with "path" in it is a sanitizer
131
- call .getAChild * ( ) .( AttrNode ) .getName ( ) .matches ( "%path" )
132
- or
133
- call .getAChild * ( ) .( NameNode ) .getId ( ) .matches ( "%path" )
134
- )
135
- }
136
-
137
- override predicate checks ( ControlFlowNode checked , boolean branch ) {
138
- checked = tarInfo and
139
- branch in [ true , false ]
146
+ this = DataFlow:: BarrierGuard< tarFileInfoSanitizer / 3 > :: getABarrierNode ( )
140
147
}
141
148
}
142
149
}
0 commit comments