@@ -1060,7 +1060,11 @@ private module StdlibPrivate {
1060
1060
private class OsSystemCall extends SystemCommandExecution:: Range , DataFlow:: CallCfgNode {
1061
1061
OsSystemCall ( ) { this = os ( ) .getMember ( "system" ) .getACall ( ) }
1062
1062
1063
- override DataFlow:: Node getCommand ( ) { result = this .getArg ( 0 ) }
1063
+ override DataFlow:: Node getCommand ( ) {
1064
+ result in [ this .getArg ( 0 ) , this .getArgByName ( "command" ) ]
1065
+ }
1066
+
1067
+ override predicate isShellInterpreted ( DataFlow:: Node arg ) { arg = this .getCommand ( ) }
1064
1068
}
1065
1069
1066
1070
/**
@@ -1071,7 +1075,7 @@ private module StdlibPrivate {
1071
1075
* Although deprecated since version 2.6, they still work in 2.7.
1072
1076
* See https://docs.python.org/2.7/library/os.html#os.popen2
1073
1077
*/
1074
- private class OsPopenCall extends SystemCommandExecution:: Range , DataFlow :: CallCfgNode {
1078
+ private class OsPopenCall extends SystemCommandExecution:: Range , API :: CallNode {
1075
1079
string name ;
1076
1080
1077
1081
OsPopenCall ( ) {
@@ -1085,6 +1089,8 @@ private module StdlibPrivate {
1085
1089
not name = "popen" and
1086
1090
result = this .getArgByName ( "cmd" )
1087
1091
}
1092
+
1093
+ override predicate isShellInterpreted ( DataFlow:: Node arg ) { arg = this .getCommand ( ) }
1088
1094
}
1089
1095
1090
1096
/**
@@ -1103,6 +1109,10 @@ private module StdlibPrivate {
1103
1109
override DataFlow:: Node getCommand ( ) { result = this .getArg ( 0 ) }
1104
1110
1105
1111
override DataFlow:: Node getAPathArgument ( ) { result = this .getCommand ( ) }
1112
+
1113
+ override predicate isShellInterpreted ( DataFlow:: Node arg ) {
1114
+ none ( ) // this is a safe API.
1115
+ }
1106
1116
}
1107
1117
1108
1118
/**
@@ -1129,6 +1139,10 @@ private module StdlibPrivate {
1129
1139
}
1130
1140
1131
1141
override DataFlow:: Node getAPathArgument ( ) { result = this .getCommand ( ) }
1142
+
1143
+ override predicate isShellInterpreted ( DataFlow:: Node arg ) {
1144
+ none ( ) // this is a safe API.
1145
+ }
1132
1146
}
1133
1147
1134
1148
/**
@@ -1142,6 +1156,10 @@ private module StdlibPrivate {
1142
1156
override DataFlow:: Node getCommand ( ) { result in [ this .getArg ( 0 ) , this .getArgByName ( "path" ) ] }
1143
1157
1144
1158
override DataFlow:: Node getAPathArgument ( ) { result = this .getCommand ( ) }
1159
+
1160
+ override predicate isShellInterpreted ( DataFlow:: Node arg ) {
1161
+ none ( ) // this is a safe API.
1162
+ }
1145
1163
}
1146
1164
1147
1165
/** An additional taint step for calls to `os.path.join` */
@@ -1186,6 +1204,7 @@ private module StdlibPrivate {
1186
1204
}
1187
1205
1188
1206
private boolean get_shell_arg_value ( ) {
1207
+ // TODO: API-node this thing - with added tests for unsafe-shell-command-construction
1189
1208
not exists ( this .get_shell_arg ( ) ) and
1190
1209
result = false
1191
1210
or
@@ -1239,6 +1258,11 @@ private module StdlibPrivate {
1239
1258
)
1240
1259
)
1241
1260
}
1261
+
1262
+ override predicate isShellInterpreted ( DataFlow:: Node arg ) {
1263
+ arg = this .get_executable_arg ( ) and
1264
+ this .get_shell_arg_value ( ) = true
1265
+ }
1242
1266
}
1243
1267
1244
1268
// ---------------------------------------------------------------------------
@@ -1385,6 +1409,8 @@ private module StdlibPrivate {
1385
1409
}
1386
1410
1387
1411
override DataFlow:: Node getCommand ( ) { result in [ this .getArg ( 0 ) , this .getArgByName ( "cmd" ) ] }
1412
+
1413
+ override predicate isShellInterpreted ( DataFlow:: Node arg ) { arg = this .getCommand ( ) }
1388
1414
}
1389
1415
1390
1416
// ---------------------------------------------------------------------------
@@ -1401,6 +1427,8 @@ private module StdlibPrivate {
1401
1427
PlatformPopenCall ( ) { this = platform ( ) .getMember ( "popen" ) .getACall ( ) }
1402
1428
1403
1429
override DataFlow:: Node getCommand ( ) { result in [ this .getArg ( 0 ) , this .getArgByName ( "cmd" ) ] }
1430
+
1431
+ override predicate isShellInterpreted ( DataFlow:: Node arg ) { arg = this .getCommand ( ) }
1404
1432
}
1405
1433
1406
1434
// ---------------------------------------------------------------------------
0 commit comments