Skip to content

Commit fc528a6

Browse files
authored
Merge branch 'beta' into fix/method-chain-merge
2 parents e6d8923 + ec8ecb3 commit fc528a6

38 files changed

+768
-620
lines changed

dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/controller/impl/PropagatorImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ private static void addPropagator(PropagatorNode propagatorNode, MethodEvent eve
4545
Set<TaintPosition> sources = propagatorNode.getSources();
4646
Set<TaintPosition> targets = propagatorNode.getTargets();
4747

48-
TaintCommandRunner r = TaintCommandRunner.getCommandRunner(event.signature);
48+
TaintCommandRunner r = propagatorNode.getCommandRunner();
4949
// O => O || O => R, source equals target and no change in taint range
5050
if (event.getSourceHashes().equals(event.getTargetHashes())
5151
&& sources.size() == 1 && targets.size() == 1
@@ -176,7 +176,7 @@ private static TaintRanges getTaintRanges(Object obj) {
176176
}
177177

178178
private static void trackTaintRange(PropagatorNode propagatorNode, MethodEvent event) {
179-
TaintCommandRunner r = TaintCommandRunner.getCommandRunner(event.signature);
179+
TaintCommandRunner r = propagatorNode.getCommandRunner();
180180

181181
TaintRanges oldTaintRanges = new TaintRanges();
182182
TaintRanges srcTaintRanges = new TaintRanges();

dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/models/policy/PolicyBuilder.java

Lines changed: 142 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
import com.alibaba.fastjson.JSONException;
66
import com.alibaba.fastjson.JSONObject;
77
import io.dongtai.iast.common.constants.ApiPath;
8+
import io.dongtai.iast.core.handler.hookpoint.models.taint.range.TaintCommand;
9+
import io.dongtai.iast.core.handler.hookpoint.models.taint.range.TaintCommandRunner;
10+
import io.dongtai.iast.core.handler.hookpoint.models.taint.tag.TaintTag;
811
import io.dongtai.iast.core.handler.hookpoint.vulscan.VulnType;
912
import io.dongtai.iast.core.utils.HttpClientUtils;
1013
import io.dongtai.iast.core.utils.StringUtils;
@@ -24,7 +27,10 @@ public class PolicyBuilder {
2427
private static final String KEY_SIGNATURE = "signature";
2528
private static final String KEY_INHERIT = "inherit";
2629
private static final String KEY_VUL_TYPE = "vul_type";
30+
private static final String KEY_TAGS = "tags";
31+
private static final String KEY_UNTAGS = "untags";
2732
private static final String KEY_COMMAND = "command";
33+
private static final String KEY_STACK_BLACKLIST = "stack_blacklist";
2834
private static final String KEY_IGNORE_INTERNAL = "ignore_internal";
2935
private static final String KEY_IGNORE_BLACKLIST = "ignore_blacklist";
3036

@@ -69,7 +75,7 @@ public static Policy build(JSONArray policyConfig) throws PolicyException {
6975
buildPropagator(policy, nodeType, node);
7076
buildSink(policy, nodeType, node);
7177
} catch (PolicyException e) {
72-
DongTaiLog.warn(ErrorCode.get("POLICY_CONFIG_INVALID"), e.getMessage());
78+
DongTaiLog.warn(ErrorCode.get("POLICY_CONFIG_INVALID"), e);
7379
}
7480
}
7581
return policy;
@@ -99,12 +105,12 @@ public static void buildPropagator(Policy policy, PolicyNodeType type, JSONObjec
99105
Set<TaintPosition> sources = parseSource(node, type);
100106
Set<TaintPosition> targets = parseTarget(node, type);
101107
MethodMatcher methodMatcher = buildMethodMatcher(node);
102-
// @TODO: command
103-
PropagatorNode propagatorNode = new PropagatorNode(sources, targets, null, new String[]{}, methodMatcher);
108+
PropagatorNode propagatorNode = new PropagatorNode(sources, targets, methodMatcher);
104109
setInheritable(node, propagatorNode);
105110
List<String[]> tags = parseTags(node, propagatorNode);
106111
propagatorNode.setTags(tags.get(0));
107112
propagatorNode.setUntags(tags.get(1));
113+
parseCommand(node, propagatorNode);
108114
parseFlags(node, propagatorNode);
109115
policy.addPropagator(propagatorNode);
110116
}
@@ -124,7 +130,7 @@ public static void buildSink(Policy policy, PolicyNodeType type, JSONObject node
124130
}
125131
setInheritable(node, sinkNode);
126132
sinkNode.setVulType(vulType);
127-
sinkNode.setStackDenyList(parseStackDenyList(sinkNode));
133+
parseStackDenyList(node, sinkNode);
128134
parseFlags(node, sinkNode);
129135
policy.addSink(sinkNode);
130136
}
@@ -212,43 +218,156 @@ private static MethodMatcher buildMethodMatcher(JSONObject node) throws PolicyEx
212218

213219
/**
214220
* stack deny list for sink node
215-
* TODO: parse stack deny list from policy
216221
*/
217-
private static String[] parseStackDenyList(SinkNode node) {
218-
if (!(node.getMethodMatcher() instanceof SignatureMethodMatcher)) {
219-
return new String[0];
220-
}
221-
222-
String signature = ((SignatureMethodMatcher) node.getMethodMatcher()).getSignature().toString();
223-
if ("java.lang.Class.forName(java.lang.String)".equals(signature)) {
224-
return new String[]{"java.net.URL.getURLStreamHandler"};
225-
} else if ("java.lang.Class.forName(java.lang.String,boolean,java.lang.ClassLoader)".equals(signature)) {
226-
return new String[]{"org.jruby.javasupport.JavaSupport.loadJavaClass"};
222+
private static void parseStackDenyList(JSONObject node, SinkNode sinkNode) {
223+
try {
224+
if (node.has(KEY_STACK_BLACKLIST)) {
225+
JSONArray arr = node.getJSONArray(KEY_STACK_BLACKLIST);
226+
sinkNode.setStackDenyList(arr.toList().toArray(new String[0]));
227+
}
228+
} catch (JSONException ignore) {
229+
DongTaiLog.warn(ErrorCode.get("POLICY_CONFIG_INVALID"),
230+
new PolicyException(PolicyException.ERR_POLICY_NODE_STACK_BLACKLIST_INVALID + ": " + node.toString()));
231+
} catch (ArrayStoreException ignore) {
232+
DongTaiLog.warn(ErrorCode.get("POLICY_CONFIG_INVALID"),
233+
new PolicyException(PolicyException.ERR_POLICY_NODE_STACK_BLACKLIST_INVALID + ": " + node.toString()));
227234
}
228-
229-
return new String[0];
230235
}
231236

232237
private static List<String[]> parseTags(JSONObject node, PolicyNode policyNode) {
233238
List<String[]> empty = Arrays.asList(new String[0], new String[0]);
234239
if (!(policyNode.getMethodMatcher() instanceof SignatureMethodMatcher)) {
235240
return empty;
236241
}
237-
String signature = ((SignatureMethodMatcher) policyNode.getMethodMatcher()).getSignature().toString();
238242

239-
// TODO: parse tags/untags from policy
240-
List<String[]> taintTags = PolicyTag.TAGS.get(signature);
241-
if (taintTags == null || taintTags.size() != 2) {
242-
return empty;
243+
boolean hasInvalid = false;
244+
List<String> tags = new ArrayList<String>();
245+
List<String> untags = new ArrayList<String>();
246+
try {
247+
if (node.has(KEY_TAGS)) {
248+
JSONArray ts = node.getJSONArray(KEY_TAGS);
249+
for (Object o : ts) {
250+
String t = (String) o;
251+
if (TaintTag.UNTRUSTED.equals(t)) {
252+
continue;
253+
}
254+
if (TaintTag.get(t) != null) {
255+
tags.add(TaintTag.get(t).getKey());
256+
} else {
257+
hasInvalid = true;
258+
}
259+
}
260+
}
261+
} catch (JSONException ignore) {
262+
hasInvalid = true;
263+
} catch (ClassCastException ignore) {
264+
hasInvalid = true;
265+
}
266+
267+
try {
268+
if (node.has(KEY_TAGS)) {
269+
JSONArray uts = node.getJSONArray(KEY_UNTAGS);
270+
for (Object o : uts) {
271+
String ut = (String) o;
272+
if (TaintTag.UNTRUSTED.equals(ut)) {
273+
continue;
274+
}
275+
TaintTag tt = TaintTag.get(ut);
276+
if (tt != null) {
277+
if (tags.contains(tt.getKey())) {
278+
hasInvalid = true;
279+
}
280+
untags.add(tt.getKey());
281+
} else {
282+
hasInvalid = true;
283+
}
284+
}
285+
}
286+
} catch (JSONException ignore) {
287+
hasInvalid = true;
288+
} catch (ClassCastException ignore) {
289+
hasInvalid = true;
243290
}
244291

245-
return taintTags;
292+
if (hasInvalid) {
293+
DongTaiLog.warn(ErrorCode.get("POLICY_CONFIG_INVALID"),
294+
new PolicyException(PolicyException.ERR_POLICY_NODE_TAGS_UNTAGS_INVALID + ": " + node.toString()));
295+
}
296+
297+
return Arrays.asList(tags.toArray(new String[0]), untags.toArray(new String[0]));
298+
}
299+
300+
private static void parseCommand(JSONObject node, PropagatorNode propagatorNode) {
301+
try {
302+
if (node.has(KEY_COMMAND)) {
303+
String cmdConfig = node.getString(KEY_COMMAND);
304+
if (cmdConfig == null) {
305+
return;
306+
}
307+
cmdConfig = cmdConfig.trim();
308+
if (cmdConfig.isEmpty()) {
309+
return;
310+
}
311+
312+
boolean isInvalid = false;
313+
int parametersStartIndex = cmdConfig.indexOf("(");
314+
int parametersEndIndex = cmdConfig.indexOf(")");
315+
316+
if (parametersStartIndex <= 0 || parametersEndIndex <= 1
317+
|| parametersStartIndex > parametersEndIndex
318+
|| parametersEndIndex != cmdConfig.length() - 1) {
319+
isInvalid = true;
320+
} else {
321+
String cmd = cmdConfig.substring(0, parametersStartIndex).trim();
322+
String argumentsStr = cmdConfig.substring(parametersStartIndex + 1, parametersEndIndex).trim();
323+
String[] arguments = new String[]{};
324+
if (!argumentsStr.isEmpty()) {
325+
argumentsStr = argumentsStr.toUpperCase();
326+
arguments = argumentsStr.replace(" ", "").split(",");
327+
for (String argument : arguments) {
328+
String dig = argument;
329+
if (dig.startsWith("P")) {
330+
dig = dig.substring(1);
331+
}
332+
if (!dig.matches("\\d+")) {
333+
isInvalid = true;
334+
break;
335+
}
336+
}
337+
}
338+
339+
TaintCommand command = TaintCommand.get(cmd);
340+
if (command == null) {
341+
isInvalid = true;
342+
} else {
343+
if (!(propagatorNode.getMethodMatcher() instanceof SignatureMethodMatcher)) {
344+
return;
345+
}
346+
String signature = ((SignatureMethodMatcher) propagatorNode.getMethodMatcher()).getSignature().toString();
347+
TaintCommandRunner commandRunner = TaintCommandRunner.create(signature, command, arguments);
348+
propagatorNode.setCommandRunner(commandRunner);
349+
}
350+
}
351+
352+
if (isInvalid) {
353+
DongTaiLog.warn(ErrorCode.get("POLICY_CONFIG_INVALID"),
354+
new PolicyException(PolicyException.ERR_POLICY_NODE_RANGE_COMMAND_INVALID + ": " + node.toString()));
355+
}
356+
}
357+
} catch (JSONException ignore) {
358+
DongTaiLog.warn(ErrorCode.get("POLICY_CONFIG_INVALID"),
359+
new PolicyException(PolicyException.ERR_POLICY_NODE_RANGE_COMMAND_INVALID + ": " + node.toString()));
360+
}
246361
}
247362

248363
private static void parseFlags(JSONObject node, PolicyNode policyNode) {
249364
try {
250365
boolean ignoreInternal = node.getBoolean(KEY_IGNORE_INTERNAL);
251366
policyNode.setIgnoreInternal(ignoreInternal);
367+
} catch (JSONException ignore) {
368+
}
369+
370+
try {
252371
boolean ignoreBlackList = node.getBoolean(KEY_IGNORE_BLACKLIST);
253372
policyNode.setIgnoreBlacklist(ignoreBlackList);
254373
} catch (JSONException ignore) {

dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/models/policy/PolicyException.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ public class PolicyException extends Exception {
1212
public static final String ERR_POLICY_NODE_SOURCE_INVALID = "policy node source is invalid";
1313
public static final String ERR_POLICY_NODE_TARGET_INVALID = "policy node target is invalid";
1414
public static final String ERR_POLICY_SINK_NODE_VUL_TYPE_INVALID = "policy sink node vul type is invalid";
15+
public static final String ERR_POLICY_NODE_TAGS_UNTAGS_INVALID = "policy node tags/untags has invalid config";
16+
public static final String ERR_POLICY_NODE_RANGE_COMMAND_INVALID = "policy node range command is invalid";
17+
public static final String ERR_POLICY_NODE_STACK_BLACKLIST_INVALID = "policy node stack blacklist is invalid";
1518

1619
public PolicyException(String message) {
1720
super(message);

0 commit comments

Comments
 (0)