@@ -98,53 +98,30 @@ module TaintedPath {
9898 not ( isNormalized ( ) and isAbsolute ( ) )
9999 }
100100 }
101-
102- /**
103- * Gets the possible Posix path labels corresponding to `label`.
104- *
105- * A posix path label is just mapped to itself, but `data` and `taint` are assumed
106- * to be fully user-controlled, and thus map to every possible posix path label.
107- */
108- PosixPath toPosixPath ( DataFlow:: FlowLabel label ) {
109- result = label
110- or
111- label instanceof DataFlow:: StandardFlowLabel
112- }
113- }
114-
115- /** Gets any flow label. */
116- private DataFlow:: FlowLabel anyLabel ( ) { any ( ) }
117-
118- /**
119- * Maps any label to itself, except `data` which is mapped to `taint`.
120- */
121- private predicate preserveLabel ( DataFlow:: FlowLabel srclabel , DataFlow:: FlowLabel dstlabel ) {
122- srclabel != DataFlow:: FlowLabel:: data ( ) and
123- dstlabel = srclabel
124- or
125- srclabel = DataFlow:: FlowLabel:: data ( ) and
126- dstlabel = DataFlow:: FlowLabel:: taint ( )
127101 }
128102
129103 /**
130104 * A taint-tracking configuration for reasoning about tainted-path vulnerabilities.
131105 */
132- class Configuration extends TaintTracking :: Configuration {
106+ class Configuration extends DataFlow :: Configuration {
133107 Configuration ( ) { this = "TaintedPath" }
134108
135- override predicate isSource ( DataFlow:: Node source ) { source instanceof Source }
109+ override predicate isSource ( DataFlow:: Node source , DataFlow:: FlowLabel label ) {
110+ source instanceof Source and
111+ label instanceof Label:: PosixPath
112+ }
136113
137114 override predicate isSink ( DataFlow:: Node sink , DataFlow:: FlowLabel label ) {
138115 sink instanceof Sink and
139- label = anyLabel ( )
116+ label instanceof Label :: PosixPath
140117 }
141118
142- override predicate isSanitizer ( DataFlow:: Node node ) {
143- super .isSanitizer ( node ) or
119+ override predicate isBarrier ( DataFlow:: Node node ) {
120+ super .isBarrier ( node ) or
144121 node instanceof Sanitizer
145122 }
146123
147- override predicate isSanitizerGuard ( TaintTracking :: SanitizerGuardNode guard ) {
124+ override predicate isBarrierGuard ( DataFlow :: BarrierGuardNode guard ) {
148125 guard instanceof StartsWithDotDotSanitizer or
149126 guard instanceof StartsWithDirSanitizer or
150127 guard instanceof IsAbsoluteSanitizer or
@@ -168,7 +145,7 @@ module TaintedPath {
168145 or
169146 // Ignore all preliminary sanitization after decoding URI components
170147 srclabel instanceof Label:: PosixPath and
171- dstlabel = DataFlow :: FlowLabel :: taint ( ) and
148+ dstlabel instanceof Label :: PosixPath and
172149 (
173150 any ( UriLibraryStep step ) .step ( src , dst )
174151 or
@@ -179,49 +156,54 @@ module TaintedPath {
179156 dst = decode
180157 )
181158 )
182- }
183-
184- override predicate isOmittedTaintStep ( DataFlow:: Node src , DataFlow:: Node dst ) {
185- isTaintedPathStep ( src , dst , _, _)
159+ or
160+ promiseTaintStep ( src , dst ) and srclabel = dstlabel
161+ or
162+ any ( TaintTracking:: PersistentStorageTaintStep st ) .step ( src , dst ) and srclabel = dstlabel
163+ or
164+ exists ( DataFlow:: PropRead read | read = dst |
165+ src = read .getBase ( ) and
166+ read .getPropertyName ( ) != "length" and
167+ srclabel = dstlabel
168+ )
186169 }
187170
188171 /**
189172 * Holds if we should include a step from `src -> dst` with labels `srclabel -> dstlabel`, and the
190173 * standard taint step `src -> dst` should be suppresesd.
191174 */
192175 predicate isTaintedPathStep (
193- DataFlow:: Node src , DataFlow:: Node dst , DataFlow :: FlowLabel srclabel ,
194- DataFlow :: FlowLabel dstlabel
176+ DataFlow:: Node src , DataFlow:: Node dst , Label :: PosixPath srclabel ,
177+ Label :: PosixPath dstlabel
195178 ) {
196179 // path.normalize() and similar
197180 exists ( NormalizingPathCall call |
198181 src = call .getInput ( ) and
199182 dst = call .getOutput ( ) and
200- dstlabel = Label :: toPosixPath ( srclabel ) .toNormalized ( )
183+ dstlabel = srclabel .toNormalized ( )
201184 )
202185 or
203186 // path.resolve() and similar
204187 exists ( ResolvingPathCall call |
205188 src = call .getInput ( ) and
206189 dst = call .getOutput ( ) and
207- srclabel = anyLabel ( ) and
208- dstlabel .( Label:: PosixPath ) .isAbsolute ( ) and
209- dstlabel .( Label:: PosixPath ) .isNormalized ( )
190+ dstlabel .isAbsolute ( ) and
191+ dstlabel .isNormalized ( )
210192 )
211193 or
212194 // path.relative() and similar
213195 exists ( NormalizingRelativePathCall call |
214196 src = call .getInput ( ) and
215197 dst = call .getOutput ( ) and
216- dstlabel .( Label :: PosixPath ) . isRelative ( ) and
217- dstlabel .( Label :: PosixPath ) . isNormalized ( )
198+ dstlabel .isRelative ( ) and
199+ dstlabel .isNormalized ( )
218200 )
219201 or
220202 // path.dirname() and similar
221203 exists ( PreservingPathCall call |
222204 src = call .getInput ( ) and
223205 dst = call .getOutput ( ) and
224- preserveLabel ( srclabel , dstlabel )
206+ srclabel = dstlabel
225207 )
226208 or
227209 // path.join()
@@ -233,12 +215,12 @@ module TaintedPath {
233215 (
234216 // If the initial argument is tainted, just normalize it. It can be relative or absolute.
235217 n = 0 and
236- dstlabel = Label :: toPosixPath ( srclabel ) .toNormalized ( )
218+ dstlabel = srclabel .toNormalized ( )
237219 or
238220 // For later arguments, the flow label depends on whether the first argument is absolute or relative.
239221 // If in doubt, we assume it is absolute.
240222 n > 0 and
241- Label :: toPosixPath ( srclabel ) .canContainDotDotSlash ( ) and
223+ srclabel .canContainDotDotSlash ( ) and
242224 dstlabel .( Label:: PosixPath ) .isNormalized ( ) and
243225 if isRelative ( join .getArgument ( 0 ) .getStringValue ( ) )
244226 then dstlabel .( Label:: PosixPath ) .isRelative ( )
@@ -252,10 +234,10 @@ module TaintedPath {
252234 |
253235 // use ordinary taint flow for the first operand
254236 n = 0 and
255- preserveLabel ( srclabel , dstlabel )
237+ srclabel = dstlabel
256238 or
257239 n > 0 and
258- Label :: toPosixPath ( srclabel ) .canContainDotDotSlash ( ) and
240+ srclabel .canContainDotDotSlash ( ) and
259241 dstlabel .( Label:: PosixPath ) .isNonNormalized ( ) and // The ../ is no longer at the beginning of the string.
260242 (
261243 if isRelative ( StringConcatenation:: getOperand ( operator , 0 ) .getStringValue ( ) )
@@ -414,22 +396,22 @@ module TaintedPath {
414396 *
415397 * This is relevant for paths that are known to be normalized.
416398 */
417- class StartsWithDotDotSanitizer extends TaintTracking :: LabeledSanitizerGuardNode {
399+ class StartsWithDotDotSanitizer extends DataFlow :: LabeledBarrierGuardNode {
418400 StringOps:: StartsWith startsWith ;
419401
420402 StartsWithDotDotSanitizer ( ) {
421403 this = startsWith and
422404 isDotDotSlashPrefix ( startsWith .getSubstring ( ) )
423405 }
424406
425- override predicate sanitizes ( boolean outcome , Expr e , DataFlow:: FlowLabel label ) {
407+ override predicate blocks ( boolean outcome , Expr e , DataFlow:: FlowLabel label ) {
426408 // Sanitize in the false case for:
427409 // .startsWith(".")
428410 // .startsWith("..")
429411 // .startsWith("../")
430412 outcome = startsWith .getPolarity ( ) .booleanNot ( ) and
431413 e = startsWith .getBaseString ( ) .asExpr ( ) and
432- exists ( Label:: PosixPath posixPath | posixPath = Label :: toPosixPath ( label ) |
414+ exists ( Label:: PosixPath posixPath | posixPath = label |
433415 posixPath .isNormalized ( ) and
434416 posixPath .isRelative ( )
435417 )
@@ -440,7 +422,7 @@ module TaintedPath {
440422 * A check of form `x.startsWith(dir)` that sanitizes normalized absolute paths, since it is then
441423 * known to be in a subdirectory of `dir`.
442424 */
443- class StartsWithDirSanitizer extends TaintTracking :: LabeledSanitizerGuardNode {
425+ class StartsWithDirSanitizer extends DataFlow :: LabeledBarrierGuardNode {
444426 StringOps:: StartsWith startsWith ;
445427
446428 StartsWithDirSanitizer ( ) {
@@ -450,10 +432,10 @@ module TaintedPath {
450432 not startsWith .getSubstring ( ) .asExpr ( ) .getStringValue ( ) = "/"
451433 }
452434
453- override predicate sanitizes ( boolean outcome , Expr e , DataFlow:: FlowLabel label ) {
435+ override predicate blocks ( boolean outcome , Expr e , DataFlow:: FlowLabel label ) {
454436 outcome = startsWith .getPolarity ( ) and
455437 e = startsWith .getBaseString ( ) .asExpr ( ) and
456- exists ( Label:: PosixPath posixPath | posixPath = Label :: toPosixPath ( label ) |
438+ exists ( Label:: PosixPath posixPath | posixPath = label |
457439 posixPath .isAbsolute ( ) and
458440 posixPath .isNormalized ( )
459441 )
@@ -464,7 +446,7 @@ module TaintedPath {
464446 * A call to `path.isAbsolute` as a sanitizer for relative paths in true branch,
465447 * and a sanitizer for absolute paths in the false branch.
466448 */
467- class IsAbsoluteSanitizer extends TaintTracking :: LabeledSanitizerGuardNode {
449+ class IsAbsoluteSanitizer extends DataFlow :: LabeledBarrierGuardNode {
468450 DataFlow:: Node operand ;
469451
470452 boolean polarity ;
@@ -487,9 +469,9 @@ module TaintedPath {
487469 ) // !x.startsWith("/home") does not guarantee that x is not absolute
488470 }
489471
490- override predicate sanitizes ( boolean outcome , Expr e , DataFlow:: FlowLabel label ) {
472+ override predicate blocks ( boolean outcome , Expr e , DataFlow:: FlowLabel label ) {
491473 e = operand .asExpr ( ) and
492- exists ( Label:: PosixPath posixPath | posixPath = Label :: toPosixPath ( label ) |
474+ exists ( Label:: PosixPath posixPath | posixPath = label |
493475 outcome = polarity and posixPath .isRelative ( )
494476 or
495477 negatable = true and
@@ -502,18 +484,18 @@ module TaintedPath {
502484 /**
503485 * An expression of form `x.includes("..")` or similar.
504486 */
505- class ContainsDotDotSanitizer extends TaintTracking :: LabeledSanitizerGuardNode {
487+ class ContainsDotDotSanitizer extends DataFlow :: LabeledBarrierGuardNode {
506488 StringOps:: Includes contains ;
507489
508490 ContainsDotDotSanitizer ( ) {
509491 this = contains and
510492 isDotDotSlashPrefix ( contains .getSubstring ( ) )
511493 }
512494
513- override predicate sanitizes ( boolean outcome , Expr e , DataFlow:: FlowLabel label ) {
495+ override predicate blocks ( boolean outcome , Expr e , DataFlow:: FlowLabel label ) {
514496 e = contains .getBaseString ( ) .asExpr ( ) and
515497 outcome = contains .getPolarity ( ) .booleanNot ( ) and
516- Label:: toPosixPath ( label ) .canContainDotDotSlash ( ) // can still be bypassed by normalized absolute path
498+ label . ( Label:: PosixPath ) .canContainDotDotSlash ( ) // can still be bypassed by normalized absolute path
517499 }
518500 }
519501
0 commit comments