@@ -32,20 +32,22 @@ module TarSlip {
3232 abstract class Sanitizer extends DataFlow:: Node { }
3333
3434 /**
35+ * DEPRECATED: Use `Sanitizer` instead.
36+ *
3537 * A sanitizer guard for "tar slip" vulnerabilities.
3638 */
37- abstract class SanitizerGuard extends DataFlow:: BarrierGuard { }
39+ abstract deprecated class SanitizerGuard extends DataFlow:: BarrierGuard { }
3840
3941 /**
40- * A source of exception info , considered as a flow source.
42+ * A call to `tarfile.open` , considered as a flow source.
4143 */
4244 class TarfileOpen extends Source {
4345 TarfileOpen ( ) {
4446 this = API:: moduleImport ( "tarfile" ) .getMember ( "open" ) .getACall ( ) and
4547 // If argument refers to a string object, then it's a hardcoded path and
4648 // this tarfile is safe.
4749 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
4951 not this .getLocation ( ) .getFile ( ) .getBaseName ( ) = "tarfile.py"
5052 }
5153 }
@@ -110,33 +112,38 @@ module TarSlip {
110112 }
111113
112114 /**
113- * A sanitizer guard heuristic .
115+ * Holds if `g` clears taint for `tarInfo` .
114116 *
115117 * The test `if <check_path>(info.name)` should clear taint for `info`,
116118 * where `<check_path>` is any function matching `"%path"`.
117119 * `info` is assumed to be a `TarInfo` instance.
118120 */
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+ }
121136
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 {
122145 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 ( )
140147 }
141148 }
142149}
0 commit comments