-
Notifications
You must be signed in to change notification settings - Fork 163
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
When using methods such as Map.get(), if the return value is an array, the elements in the array will not be tainted. #102
Comments
I can't clearly understand what you're saying. And there are so many things circled in the chart that I don't know which to focus on. Would you be so kind as to illustrate with examples/current behavior/expected behavior? |
The problem I'm trying to solve is, when the return value of the Map.get() method is an array, how do I mark the elements of the returned array with taints? package org.owasp.benchmark.testcode;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(value="/cmdi-00/BenchmarkTest00004")
public class BenchmarkTest00004 extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
java.util.Map<String,String[]> map = request.getParameterMap();
String param = "";
if (!map.isEmpty()) {
String[] values = map.get("BenchmarkTest00004");
if (values != null) param = values[0];
}
org.owasp.benchmark.helpers.ThingInterface thing = org.owasp.benchmark.helpers.ThingFactory.createThing();
String bar = thing.doSomething(param);
String cmd = "";
String osName = System.getProperty("os.name");
if (osName.indexOf("Windows") != -1) {
cmd = org.owasp.benchmark.helpers.Utils.getOSCommandString("echo");
}
Runtime r = Runtime.getRuntime();
try {
Process p = r.exec(cmd + bar);
org.owasp.benchmark.helpers.Utils.printOSCommandResults(p, response);
} catch (IOException e) {
System.out.println("Problem executing cmdi - TestCase");
response.getWriter().println(
org.owasp.esapi.ESAPI.encoder().encodeForHTML(e.getMessage())
);
return;
}
}
} |
I don't have your test environment and don't know how to reproduce your problem, in addition, you don't provide enough usable information (e.g. points-to-set, analysis options, complete analyzed program and complete Please offer the following infomation (otherwise, I don't know how to proceed.):
|
OK, I will describe my problem in detail. package org.owasp.benchmark.testcode;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(value="/cmdi-00/BenchmarkTest00016")
public class BenchmarkTest00016 extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
java.util.Map<String,String[]> map = request.getParameterMap();
String param = "";
if (!map.isEmpty()) {
String[] values = map.get("BenchmarkTest00016");
if (values != null) param = values[0];
}
String bar = doSomething(request, param);
String cmd = "";
String osName = System.getProperty("os.name");
if (osName.indexOf("Windows") != -1) {
cmd = org.owasp.benchmark.helpers.Utils.getOSCommandString("echo");
}
Runtime r = Runtime.getRuntime();
try {
Process p = r.exec(cmd + bar);
org.owasp.benchmark.helpers.Utils.printOSCommandResults(p, response);
} catch (IOException e) {
System.out.println("Problem executing cmdi - TestCase");
response.getWriter().println(
org.owasp.esapi.ESAPI.encoder().encodeForHTML(e.getMessage())
);
return;
}
} // end doPost
private static String doSomething(HttpServletRequest request, String param) throws ServletException, IOException {
String bar = param;
return bar;
}
} At line 24 of this code, I use - { method: "<org.apache.catalina.connector.RequestFacade: java.util.Map getParameterMap()>", from: base, to: result } And in line 28 of this test code, I uses the - { method: "<org.apache.catalina.util.ParameterMap: java.lang.Object get(java.lang.Object)>", from: base, to: result } After I did this, the taint propagated to the There is the source code of public Map<String,String[]> getParameterMap() {
checkFacade();
if (Globals.IS_SECURITY_ENABLED) {
return AccessController.doPrivileged(new GetParameterMapPrivilegedAction());
} else {
return request.getParameterMap();
}
} In line 7 of the above code public Map<String,String[]> getParameterMap() {
if (parameterMap.isLocked()) {
return parameterMap;
}
Enumeration<String> enumeration = getParameterNames();
while (enumeration.hasMoreElements()) {
String name = enumeration.nextElement();
String[] values = getParameterValues(name);
parameterMap.put(name, values);
}
parameterMap.setLocked(true);
return parameterMap;
} I try to usr - { method: "<org.apache.catalina.connector.Request: java.lang.String[] getParameterValues(java.lang.String)>", from: base, to: "result[*]" } But ultimately the tainflow is still undetectable. tai-e.log - id: pta
options:
cs: 1-obj
only-app: false
implicit-entries: true
distinguish-string-constants: all
merge-string-objects: false
merge-string-builders: false
merge-exception-objects: false
handle-invokedynamic: false
propagate-types:
- reference
advanced: zipper
dump: false
dump-ci: false
dump-yaml: false
expected-file: null
reflection-inference: solar
reflection-log: null
taint-config: config/common/taint-config.yml
plugins:
- pascal.taie.analysis.pta.plugin.taint.TomcatHandler
time-limit: -1
package pascal.taie.analysis.pta.plugin.taint;
import pascal.taie.World;
import pascal.taie.analysis.pta.core.cs.context.Context;
import pascal.taie.analysis.pta.core.cs.element.CSMethod;
import pascal.taie.analysis.pta.core.heap.HeapModel;
import pascal.taie.analysis.pta.core.heap.Obj;
import pascal.taie.analysis.pta.core.solver.EntryPoint;
import pascal.taie.analysis.pta.core.solver.Solver;
import pascal.taie.analysis.pta.core.solver.SpecifiedParamProvider;
import pascal.taie.analysis.pta.plugin.Plugin;
import pascal.taie.ir.IR;
import pascal.taie.ir.exp.Var;
import pascal.taie.language.classes.JClass;
import pascal.taie.language.classes.JMethod;
import pascal.taie.language.type.Type;
import java.util.List;
import static pascal.taie.analysis.pta.core.heap.Descriptor.ENTRY_DESC;
public class TomcatHandler implements Plugin {
private Solver solver;
private TaintManager manager;
private boolean isCalled;
final JClass requestFacade = World.get().getClassHierarchy().getClass("org.apache.catalina.connector.RequestFacade");
final JClass responseFacade = World.get().getClassHierarchy().getClass("org.apache.catalina.connector.ResponseFacade");
@Override
public void setSolver(Solver solver) {
this.solver = solver;
manager = new TaintManager(solver.getHeapModel());
}
@Override
public void onStart() {
List<JClass> list = solver.getHierarchy().applicationClasses().toList();
for (JClass jClass : list) {
String a = jClass.getName();
if (a.matches("^(javax\\.servlet\\.ServletRequest).+$")) {
System.out.println("found: " + a);
}
HeapModel heapModel = solver.getHeapModel();
jClass.getAnnotations().forEach(annotation -> {
if (annotation.getType().matches("javax.servlet.annotation.WebServlet")) {
jClass.getDeclaredMethods().forEach(jMethod -> {
if (jMethod.getName().matches("\\b(doGet|doPost|doPut|doDelete)\\b")) {
Type requestFacadeType = jMethod.getParamType(0);
Type responseFacadeType = jMethod.getParamType(1);
String requestFacadeAlloc = "<" + requestFacadeType.toString() + ">";
String responseFacadeAlloc = "<" + responseFacadeType.toString() + ">";
Obj mockRequest = heapModel.getMockObj(ENTRY_DESC, requestFacadeAlloc, requestFacade.getType(), jMethod);
Obj mockResponse = heapModel.getMockObj(ENTRY_DESC, responseFacadeAlloc, responseFacade.getType(), jMethod);
Obj mockServlet = heapModel.getMockObj(ENTRY_DESC, "<http-controller>", jClass.getType());
SpecifiedParamProvider paramProvider = new SpecifiedParamProvider.Builder(jMethod)
.addThisObj(mockServlet)
.addParamObj(0, mockRequest)
.addParamObj(1, mockResponse)
.build();
solver.addEntryPoint(new EntryPoint(jMethod, paramProvider));
}
});
}
}
);
}
}
@Override
public void onNewCSMethod(CSMethod csMethod) {
JMethod method = csMethod.getMethod();
Context context = csMethod.getContext();
boolean isDoMethod = method.getName().matches("\\b(doGet|doPost|doPut|doDelete)\\b");
if (isDoMethod) {
// System.out.println("find"+method.toString());
IR ir = method.getIR();
Var param = ir.getParam(0);
SourcePoint sourcePoint = new ParamSourcePoint(method, new IndexRef(IndexRef.Kind.VAR, 0, null));
Obj taint = manager.makeTaint(sourcePoint, param.getType());
solver.addVarPointsTo(context, param, taint);
}
}
} You can download the full source code from here: Thanks! |
Description
I used the following configuration:
- { method: "<org.apache.catalina.connector.Request: java.util.Map getParameterMap()>", from: base, to: result }
When I use the return value of Map.get() directly as a sink, the taint is captured, but when I use the elements of the returned array, the taint is not added.
The reality is that the specific problem is:
When I was analysing the tomcat application, I needed to use the org.apache.catalina.connector.RequestFacade.getParameterMap() method, and the obtained ParameterMap was tainted with taints, and the array obtained by ParameterMap.get() also The array obtained by ParameterMap.get() is also tainted, but when I remove an element from the array, the taint disappears.
I tried adding TRANSFER to the methods in the two images above, but still not getting the desired results.
Is there any way to fix this?
The text was updated successfully, but these errors were encountered: