pascal-lab/Tai-e

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!