Skip to content

Commit 33c506d

Browse files
committed
add minimal test for Array join as a sink, and learn that the order is flipped compared to JS. Thanks Copilot!
1 parent 5bddfc0 commit 33c506d

File tree

3 files changed

+9
-4
lines changed

3 files changed

+9
-4
lines changed

python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ module UnsafeShellCommandConstruction {
101101
* A string constructed using a `.join(" ")` call, where the resulting string ends up being executed as a shell command.
102102
*/
103103
class ArrayJoin extends Sink {
104-
// TODO: Add test.
105104
Concepts::SystemCommandExecution s;
106105
DataFlow::MethodCallNode call;
107106

@@ -110,10 +109,10 @@ module UnsafeShellCommandConstruction {
110109
unique( | | call.getArg(_)).asExpr().(Str).getText() = " " and
111110
isUsedAsShellCommand(call, s) and
112111
(
113-
this = call.getObject() and
114-
not call.getObject().asExpr() instanceof List
112+
this = call.getArg(0) and
113+
not call.getArg(0).asExpr() instanceof List
115114
or
116-
this.asExpr() = call.getObject().asExpr().(List).getASubExpression()
115+
this.asExpr() = call.getArg(0).asExpr().(List).getASubExpression()
117116
)
118117
}
119118

Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
edges
22
| src/unsafe_shell_test.py:4:22:4:25 | ControlFlowNode for name | src/unsafe_shell_test.py:5:25:5:28 | ControlFlowNode for name |
33
| src/unsafe_shell_test.py:4:22:4:25 | ControlFlowNode for name | src/unsafe_shell_test.py:8:23:8:26 | ControlFlowNode for name |
4+
| src/unsafe_shell_test.py:4:22:4:25 | ControlFlowNode for name | src/unsafe_shell_test.py:11:25:11:38 | ControlFlowNode for Attribute() |
45
nodes
56
| src/unsafe_shell_test.py:4:22:4:25 | ControlFlowNode for name | semmle.label | ControlFlowNode for name |
67
| src/unsafe_shell_test.py:5:25:5:28 | ControlFlowNode for name | semmle.label | ControlFlowNode for name |
78
| src/unsafe_shell_test.py:8:23:8:26 | ControlFlowNode for name | semmle.label | ControlFlowNode for name |
9+
| src/unsafe_shell_test.py:11:25:11:38 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
810
subpaths
911
#select
1012
| src/unsafe_shell_test.py:5:15:5:28 | ControlFlowNode for BinaryExpr | src/unsafe_shell_test.py:4:22:4:25 | ControlFlowNode for name | src/unsafe_shell_test.py:5:25:5:28 | ControlFlowNode for name | This string concatenation which depends on $@ is later used in a $@. | src/unsafe_shell_test.py:4:22:4:25 | ControlFlowNode for name | library input | src/unsafe_shell_test.py:5:5:5:29 | ControlFlowNode for Attribute() | shell command |
1113
| src/unsafe_shell_test.py:8:15:8:28 | ControlFlowNode for Fstring | src/unsafe_shell_test.py:4:22:4:25 | ControlFlowNode for name | src/unsafe_shell_test.py:8:23:8:26 | ControlFlowNode for name | This string construction which depends on $@ is later used in a $@. | src/unsafe_shell_test.py:4:22:4:25 | ControlFlowNode for name | library input | src/unsafe_shell_test.py:8:5:8:29 | ControlFlowNode for Attribute() | shell command |
14+
| src/unsafe_shell_test.py:11:15:11:38 | ControlFlowNode for BinaryExpr | src/unsafe_shell_test.py:4:22:4:25 | ControlFlowNode for name | src/unsafe_shell_test.py:11:25:11:38 | ControlFlowNode for Attribute() | This string concatenation which depends on $@ is later used in a $@. | src/unsafe_shell_test.py:4:22:4:25 | ControlFlowNode for name | library input | src/unsafe_shell_test.py:11:5:11:39 | ControlFlowNode for Attribute() | shell command |

python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/src/unsafe_shell_test.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,6 @@ def unsafe_shell_one(name):
66

77
# f-strings
88
os.system(f"ping {name}") # $result=BAD
9+
10+
# array.join
11+
os.system("ping " + " ".join(name)) # $result=BAD

0 commit comments

Comments
 (0)