Support outgoing taint flow from fields

This commit is contained in:
Benjamin Muskalla
2021-09-24 15:50:46 +02:00
parent c3462be2c9
commit cd11ef3bf6
4 changed files with 111 additions and 1 deletions

View File

@@ -11,7 +11,10 @@ import semmle.code.java.dataflow.internal.DataFlowImplCommon
string captureFlow(Callable api) {
result = captureQualifierFlow(api) or
result = captureParameterFlowToReturnValue(api)
result = captureParameterFlowToReturnValue(api) or
// TODO: merge next two?
result = captureFieldFlowOut(api) or
result = captureFieldFlowIntoParam(api)
}
string captureQualifierFlow(Callable api) {
@@ -22,6 +25,30 @@ string captureQualifierFlow(Callable api) {
result = asValueModel(api, "Argument[-1]", "ReturnValue")
}
string captureFieldFlowOut(Callable api) {
exists(FieldAccess fa, ReturnStmt rtn |
not (fa.getField().isStatic() and fa.getField().isFinal()) and
rtn.getEnclosingCallable() = api and
not api.getReturnType() instanceof PrimitiveType and
not api.getDeclaringType() instanceof EnumType and
TaintTracking::localTaint(DataFlow::exprNode(fa), DataFlow::exprNode(rtn.getResult()))
|
result = asTaintModel(api, "Argument[-1]", "ReturnValue")
)
}
string captureFieldFlowIntoParam(Callable api) {
exists(FieldAccess fa, DataFlow::PostUpdateNode pn |
not (fa.getField().isStatic() and fa.getField().isFinal()) and
pn.getPreUpdateNode().asExpr() = api.getAParameter().getAnAccess() and
TaintTracking::localTaint(DataFlow::exprNode(fa), pn)
|
result =
asTaintModel(api, "Argument[-1]",
parameterAccess(pn.getPreUpdateNode().asExpr().(VarAccess).getVariable()))
)
}
class ParameterToReturnValueTaintConfig extends TaintTracking::Configuration {
ParameterToReturnValueTaintConfig() { this = "ParameterToReturnValueTaintConfig" }

View File

@@ -0,0 +1,22 @@
package p;
public final class ImmutablePojo {
private final String value;
private final long x;
public ImmutablePojo(String value, int x) {
this.value = value;
this.x = x;
}
public String getValue() {
return value;
}
public String or(String defaultValue) {
return value != null ? value : defaultValue;
}
}

View File

@@ -0,0 +1,44 @@
package p;
import java.util.List;
public final class Pojo {
private class Holder {
private String value;
Holder(String value) {
this.value = value;
}
int length() {
return value.length();
}
}
private String value;
private int intValue = 2;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public int doNotSetValue(String value) {
Holder h = new Holder(value);
return h.length();
}
public int getIntValue() {
return intValue;
}
public void fillIn(List<String> target) {
target.add(value);
}
}

View File

@@ -0,0 +1,17 @@
package p;
enum SomeEnum {
FOO("input");
private String input;
private SomeEnum(String input) {
this.input = input;
}
public String getValue() {
return input;
}
}