What should I do if one element of the array of parameters is tainted and the whole parameter is contaminated?
struce2 opened this issue · 3 comments
Src code
<%@ page import="java.beans.Expression" %>
<%@ page import="java.io.BufferedReader" %>
<%@ page import="java.io.InputStreamReader" %>
<%@ page import="java.io.InputStream" %>
<%
String cmd = request.getParameter("x");
Expression expr = new Expression(Runtime.getRuntime(), "exec", new Object[]{cmd});
Process p = (Process)expr.getValue();
%>
If the cmd
argument is a taint, then I want to be able to pass the taint to expr, so that the taint flow can be detected when expr.getValue()
is called.
TaintConfig
sources:
- { method: "<javax.servlet.ServletRequest: java.lang.String getParameter(java.lang.String)>", type: "java.lang.String" }
- { method: "<javax.servlet.ServletRequestWrapper: java.lang.String getParameter(java.lang.String)>", type: "java.lang.String"}
sinks:
- { method: "<java.beans.Expression: java.lang.Object getValue()>", index: base }
transfers:
- { method: "<java.beans.Expression: void <init>(java.lang.Object,java.lang.String,java.lang.Object[])>", from: 2, to: base, type: "java.beans.Expression"}
Related Tai-e IR
[46@L127] %stringconst10 = "ladypwd";
[47@L127] $r25 = invokeinterface request.<javax.servlet.http.HttpServletRequest: java.lang.String getParameter(java.lang.String)>(%stringconst10);
[48@L128] $r35 = new java.beans.Expression;
[49@L128] $r27 = invokestatic <java.lang.Runtime: java.lang.Runtime getRuntime()>();
[50@L128] $r28 = newarray java.lang.Object[%intconst6];
[51@L128] $r28[%intconst0] = $r25;
[52@L128] %stringconst11 = "exec";
[53@L128] invokespecial $r35.<java.beans.Expression: void <init>(java.lang.Object,java.lang.String,java.lang.Object[])>($r27, %stringconst11, $r28);
[54@L129] $r29 = invokevirtual $r35.<java.beans.Expression: java.lang.Object getValue()>();
[55@L129] $r30 = (java.lang.Process) $r29;
Currently Tai-e cannot handle such case. Some other users also mentioned this kind of issues, and we will think of a general way to extend taint analysis for these cases later.
Tai-e's taint analysis now supports more powerful taint transfers, i.e., taint transfers among variables and instance fields/array elements. For your case, you could add transfer like (simplified here, please use fully-qualified class names in real world):
- { method: "<Expression: void <init>(Runtime,String,Object[])>", from: "2[*]", to: base }
then if the elements of the Object[]
are tainted, the taint objects will be transferred to base variable, i.e., from cmd
to expr
in:
Expression expr = new Expression(Runtime.getRuntime(), "exec", new Object[]{cmd});
You could check test cases taint-config-taint-transfer-edge.yml and TaintTransferEdge.java for more details, and we will elaborate Tai-e's taint analysis (including various taint transfers) in documentation later.
Nice!