@@ -93,13 +93,68 @@ module TaintedPath {
93
93
|
94
94
name = argumentlessMethodName
95
95
)
96
- or
96
+ )
97
+ or
98
+ // array method calls of interest
99
+ exists ( DataFlow:: MethodCallNode mcn , string name | dst = mcn and mcn .calls ( src , name ) |
100
+ // A `str.split()` call can either split into path elements (`str.split("/")`) or split by some other string.
97
101
name = "split" and
98
- not exists ( DataFlow:: Node splitBy | splitBy = mcn .getArgument ( 0 ) |
99
- splitBy .mayHaveStringValue ( "/" ) or
100
- any ( DataFlow:: RegExpLiteralNode reg | reg .getRoot ( ) .getAMatchedString ( ) = "/" )
101
- .flowsTo ( splitBy )
102
+ (
103
+ if
104
+ exists ( DataFlow:: Node splitBy | splitBy = mcn .getArgument ( 0 ) |
105
+ splitBy .mayHaveStringValue ( "/" ) or
106
+ any ( DataFlow:: RegExpCreationNode reg | reg .getRoot ( ) .getAMatchedString ( ) = "/" )
107
+ .flowsTo ( splitBy )
108
+ )
109
+ then
110
+ srclabel .( Label:: PosixPath ) .canContainDotDotSlash ( ) and
111
+ dstlabel instanceof Label:: SplitPath
112
+ else srclabel = dstlabel
102
113
)
114
+ or
115
+ (
116
+ name = "pop" or
117
+ name = "shift"
118
+ ) and
119
+ srclabel instanceof Label:: SplitPath and
120
+ dstlabel .( Label:: PosixPath ) .canContainDotDotSlash ( )
121
+ or
122
+ (
123
+ name = "slice" or
124
+ name = "splice" or
125
+ name = "concat"
126
+ ) and
127
+ dstlabel instanceof Label:: SplitPath and
128
+ srclabel instanceof Label:: SplitPath
129
+ or
130
+ name = "join" and
131
+ mcn .getArgument ( 0 ) .mayHaveStringValue ( "/" ) and
132
+ srclabel instanceof Label:: SplitPath and
133
+ dstlabel .( Label:: PosixPath ) .canContainDotDotSlash ( )
134
+ )
135
+ or
136
+ // prefix.concat(path)
137
+ exists ( DataFlow:: MethodCallNode mcn |
138
+ mcn .getMethodName ( ) = "concat" and mcn .getAnArgument ( ) = src
139
+ |
140
+ dst = mcn and
141
+ dstlabel instanceof Label:: SplitPath and
142
+ srclabel instanceof Label:: SplitPath
143
+ )
144
+ or
145
+ // reading unknown property of split path
146
+ exists ( DataFlow:: PropRead read | read = dst |
147
+ src = read .getBase ( ) and
148
+ not read .getPropertyName ( ) = "length" and
149
+ not exists ( read .getPropertyNameExpr ( ) .getIntValue ( ) ) and
150
+ // split[split.length - 1]
151
+ not exists ( BinaryExpr binop |
152
+ read .getPropertyNameExpr ( ) = binop and
153
+ binop .getAnOperand ( ) .getIntValue ( ) = 1 and
154
+ binop .getAnOperand ( ) .( PropAccess ) .getPropertyName ( ) = "length"
155
+ ) and
156
+ srclabel instanceof Label:: SplitPath and
157
+ dstlabel .( Label:: PosixPath ) .canContainDotDotSlash ( )
103
158
)
104
159
}
105
160
0 commit comments