From 7d41c8e44f1f291d218e5977acc42837e40e5bad Mon Sep 17 00:00:00 2001 From: lostsnow Date: Wed, 14 Sep 2022 18:19:16 +0800 Subject: [PATCH] support nested propagation track --- .../core/bytecode/enhance/asm/AsmMethods.java | 9 +++-- .../core/adapter/PropagateAdviceAdapter.java | 5 ++- .../handler/hookpoint/SpyDispatcherImpl.java | 13 ++++--- .../hookpoint/controller/TrackerHelper.java | 16 ++++++-- .../controller/impl/PropagatorImpl.java | 39 +++++++++++++++---- .../utils/threadlocal/IastScopeTracker.java | 8 ++-- .../main/java/java/lang/dongtai/NopSpy.java | 6 +-- .../java/java/lang/dongtai/SpyDispatcher.java | 6 +-- 8 files changed, 72 insertions(+), 30 deletions(-) diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/bytecode/enhance/asm/AsmMethods.java b/dongtai-core/src/main/java/io/dongtai/iast/core/bytecode/enhance/asm/AsmMethods.java index 4cbac568d..a8704bd39 100755 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/bytecode/enhance/asm/AsmMethods.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/bytecode/enhance/asm/AsmMethods.java @@ -103,15 +103,18 @@ static Method getAsmMethod(final Class clazz, ); Method SPY$enterPropagator = InnerHelper.getAsmMethod( SpyDispatcher.class, - "enterPropagator" + "enterPropagator", + String.class ); Method SPY$leavePropagator = InnerHelper.getAsmMethod( SpyDispatcher.class, - "leavePropagator" + "leavePropagator", + String.class ); Method SPY$isFirstLevelPropagator = InnerHelper.getAsmMethod( SpyDispatcher.class, - "isFirstLevelPropagator" + "isFirstLevelPropagator", + String.class ); Method SPY$enterSink = InnerHelper.getAsmMethod( SpyDispatcher.class, diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/bytecode/enhance/plugin/core/adapter/PropagateAdviceAdapter.java b/dongtai-core/src/main/java/io/dongtai/iast/core/bytecode/enhance/plugin/core/adapter/PropagateAdviceAdapter.java index 6b3daf95a..d41ed6264 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/bytecode/enhance/plugin/core/adapter/PropagateAdviceAdapter.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/bytecode/enhance/plugin/core/adapter/PropagateAdviceAdapter.java @@ -1,9 +1,9 @@ package io.dongtai.iast.core.bytecode.enhance.plugin.core.adapter; -import io.dongtai.iast.core.utils.PropertyUtils; import io.dongtai.iast.core.bytecode.enhance.IastContext; import io.dongtai.iast.core.bytecode.enhance.plugin.AbstractAdviceAdapter; import io.dongtai.iast.core.handler.hookpoint.controller.HookType; +import io.dongtai.iast.core.utils.PropertyUtils; import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; @@ -34,6 +34,7 @@ protected void after(final int opcode) { Label elseLabel = new Label(); Label endLabel = new Label(); invokeStatic(ASM_TYPE_SPY_HANDLER, SPY_HANDLER$getDispatcher); + push(signature); invokeInterface(ASM_TYPE_SPY_DISPATCHER, SPY$isFirstLevelPropagator); mv.visitJumpInsn(EQ, elseLabel); captureMethodState(opcode, HookType.PROPAGATOR.getValue(), true); @@ -50,11 +51,13 @@ protected void after(final int opcode) { private void enterPropagator() { invokeStatic(ASM_TYPE_SPY_HANDLER, SPY_HANDLER$getDispatcher); + push(signature); invokeInterface(ASM_TYPE_SPY_DISPATCHER, SPY$enterPropagator); } private void leavePropagator() { invokeStatic(ASM_TYPE_SPY_HANDLER, SPY_HANDLER$getDispatcher); + push(signature); invokeInterface(ASM_TYPE_SPY_DISPATCHER, SPY$leavePropagator); } } diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/SpyDispatcherImpl.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/SpyDispatcherImpl.java index 9d771a116..2edeb8d09 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/SpyDispatcherImpl.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/SpyDispatcherImpl.java @@ -279,11 +279,11 @@ public boolean isFirstLevelSource() { * @since 1.3.1 */ @Override - public void enterPropagator() { + public void enterPropagator(String signature) { try { if (EngineManager.isDongTaiRunning() && EngineManager.isEngineRunning()) { EngineManager.turnOffDongTai(); - EngineManager.SCOPE_TRACKER.enterPropagation(); + EngineManager.SCOPE_TRACKER.enterPropagation(PropagatorImpl.isSkipScope(signature)); EngineManager.turnOnDongTai(); } } catch (Exception e) { @@ -297,11 +297,11 @@ public void enterPropagator() { * @since 1.3.1 */ @Override - public void leavePropagator() { + public void leavePropagator(String signature) { try { if (EngineManager.isDongTaiRunning() && EngineManager.isEngineRunning()) { EngineManager.turnOffDongTai(); - EngineManager.SCOPE_TRACKER.leavePropagation(); + EngineManager.SCOPE_TRACKER.leavePropagation(PropagatorImpl.isSkipScope(signature)); EngineManager.turnOnDongTai(); } } catch (Exception e) { @@ -316,9 +316,10 @@ public void leavePropagator() { * @since 1.3.1 */ @Override - public boolean isFirstLevelPropagator() { + public boolean isFirstLevelPropagator(String signature) { try { - return EngineManager.isDongTaiRunning() && EngineManager.isEngineRunning() && EngineManager.SCOPE_TRACKER.isFirstLevelPropagator(); + return EngineManager.isDongTaiRunning() && EngineManager.isEngineRunning() + && EngineManager.SCOPE_TRACKER.isFirstLevelPropagator(); } catch (Exception e) { return false; } diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/controller/TrackerHelper.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/controller/TrackerHelper.java index d6f397829..c13ef00d5 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/controller/TrackerHelper.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/controller/TrackerHelper.java @@ -7,6 +7,10 @@ public class TrackerHelper { private int trackCounts = 0; private int propagationDepth = 0; + /** + * TODO: for nested propagation track + */ + private int propagationSkipDepth = 0; private int sourceLevel = 0; private int enterHttp = 0; private int leaveSource = 0; @@ -30,16 +34,22 @@ public void leaveTrack() { this.trackCounts--; } - public void enterPropagation() { + public void enterPropagation(boolean isSkipScope) { if (isEnterEntry()) { this.propagationDepth++; } + if (isSkipScope) { + this.propagationSkipDepth++; + } } - public void leavePropagation() { + public void leavePropagation(boolean isSkipScope) { if (isEnterEntry()) { this.propagationDepth--; } + if (isSkipScope) { + this.propagationSkipDepth--; + } } /** @@ -49,7 +59,7 @@ public void leavePropagation() { */ public boolean isFirstLevelPropagator() { return isEnterEntry() && this.sourceLevel == 0 && this.leaveSource == 1 - && this.propagationDepth == 1; + && (this.propagationDepth == 1 || this.propagationSkipDepth > 0); } public void enterHttp() { diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/controller/impl/PropagatorImpl.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/controller/impl/PropagatorImpl.java index c93ed8a36..d50b36a05 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/controller/impl/PropagatorImpl.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/controller/impl/PropagatorImpl.java @@ -7,8 +7,7 @@ import io.dongtai.iast.core.utils.StackUtils; import io.dongtai.iast.core.utils.TaintPoolUtils; -import java.util.ArrayList; -import java.util.Set; +import java.util.*; import java.util.concurrent.atomic.AtomicInteger; /** @@ -25,6 +24,20 @@ public class PropagatorImpl { private static final String CONDITION_AND_RE_PATTERN = "[\\|&]"; private static final int STACK_DEPTH = 11; + private final static Set SKIP_SCOPE_METHODS = new HashSet(Arrays.asList( + "java.net.URI.(java.lang.String)", + "java.net.URI.(java.lang.String,java.lang.String,java.lang.String)", + "java.net.URI.(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String)", + "java.net.URI.(java.lang.String,java.lang.String,java.lang.String,java.lang.String)", // indirect + "java.net.URI.(java.lang.String,java.lang.String,java.lang.String,int,java.lang.String,java.lang.String,java.lang.String)", + "java.net.URL.(java.lang.String)", // indirect + "java.net.URL.(java.net.URL,java.lang.String)", // indirect + "java.net.URL.(java.net.URL,java.lang.String,java.net.URLStreamHandler)", + "java.net.URL.(java.lang.String,java.lang.String,java.lang.String)", // indirect + "java.net.URL.(java.lang.String,java.lang.String,int,java.lang.String)", // indirect + "java.net.URL.(java.lang.String,java.lang.String,int,java.lang.String,java.net.URLStreamHandler)" + )); + public static void solvePropagator(MethodEvent event, AtomicInteger invokeIdSequencer) { if (!EngineManager.TAINT_POOL.isEmpty()) { IastPropagatorModel propagator = IastHookRuleModel.getPropagatorByMethodSignature(event.signature); @@ -36,7 +49,15 @@ public static void solvePropagator(MethodEvent event, AtomicInteger invokeIdSequ } } - private static void addPropagator(MethodEvent event, AtomicInteger invokeIdSequencer) { + private static void addPropagator(IastPropagatorModel propagator, MethodEvent event, AtomicInteger invokeIdSequencer) { + // skip same source and target + if (event.getSourceHashes().size() == event.getTargetHashes().size() + && event.getSourceHashes().equals(event.getTargetHashes()) + && propagator != null + && !(PARAMS_OBJECT.equals(propagator.getSource()) && PARAMS_OBJECT.equals(propagator.getTarget()))) { + return; + } + event.source = false; event.setCallStacks(StackUtils.createCallStack(6)); int invokeId = invokeIdSequencer.getAndIncrement(); @@ -57,7 +78,7 @@ private static void auxiliaryPropagator(IastPropagatorModel propagator, AtomicIn event.setInValue(event.object); setTarget(propagator, event); - addPropagator(event, invokeIdSequencer); + addPropagator(propagator, event, invokeIdSequencer); } else if (sourceString.startsWith(PARAMS_PARAM)) { ArrayList inValues = new ArrayList(); int[] positions = (int[]) propagator.getSourcePosition(); @@ -77,7 +98,7 @@ private static void auxiliaryPropagator(IastPropagatorModel propagator, AtomicIn if (!inValues.isEmpty()) { event.setInValue(inValues.toArray()); setTarget(propagator, event); - addPropagator(event, invokeIdSequencer); + addPropagator(propagator, event, invokeIdSequencer); } } } else { @@ -119,7 +140,7 @@ private static void auxiliaryPropagator(IastPropagatorModel propagator, AtomicIn if (condition > 0 && (!andCondition || conditionSources.length == condition)) { event.setInValue(inValues.toArray()); setTarget(propagator, event); - addPropagator(event, invokeIdSequencer); + addPropagator(propagator, event, invokeIdSequencer); } } } @@ -263,10 +284,14 @@ private static void autoPropagator(AtomicInteger invokeIdSequence, MethodEvent e } else { event.addTargetHash(event.outValue.hashCode()); } - addPropagator(event, invokeIdSequence); + addPropagator(null, event, invokeIdSequence); } } + public static boolean isSkipScope(String signature) { + return SKIP_SCOPE_METHODS.contains(signature); + } + private static boolean contains(String obj) { return obj.contains(CONDITION_AND) || obj.contains(CONDITION_OR); } diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/utils/threadlocal/IastScopeTracker.java b/dongtai-core/src/main/java/io/dongtai/iast/core/utils/threadlocal/IastScopeTracker.java index 4a73fe361..1b1f2ac92 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/utils/threadlocal/IastScopeTracker.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/utils/threadlocal/IastScopeTracker.java @@ -52,12 +52,12 @@ public boolean isFirstLevelSource() { return this.get().isFirstLevelSource(); } - public void enterPropagation() { - this.get().enterPropagation(); + public void enterPropagation(boolean isSkipScope) { + this.get().enterPropagation(isSkipScope); } - public void leavePropagation() { - this.get().leavePropagation(); + public void leavePropagation(boolean isSkipScope) { + this.get().leavePropagation(isSkipScope); } public boolean isFirstLevelPropagator() { diff --git a/dongtai-spy/src/main/java/java/lang/dongtai/NopSpy.java b/dongtai-spy/src/main/java/java/lang/dongtai/NopSpy.java index fc9e42dcd..e6a796d09 100644 --- a/dongtai-spy/src/main/java/java/lang/dongtai/NopSpy.java +++ b/dongtai-spy/src/main/java/java/lang/dongtai/NopSpy.java @@ -150,7 +150,7 @@ public boolean isFirstLevelSource() { * @since 1.3.1 */ @Override - public void enterPropagator() { + public void enterPropagator(String signature) { } @@ -160,7 +160,7 @@ public void enterPropagator() { * @since 1.3.1 */ @Override - public void leavePropagator() { + public void leavePropagator(String signature) { } @@ -171,7 +171,7 @@ public void leavePropagator() { * @since 1.3.1 */ @Override - public boolean isFirstLevelPropagator() { + public boolean isFirstLevelPropagator(String signature) { return false; } diff --git a/dongtai-spy/src/main/java/java/lang/dongtai/SpyDispatcher.java b/dongtai-spy/src/main/java/java/lang/dongtai/SpyDispatcher.java index f1d1860c1..0accc587e 100644 --- a/dongtai-spy/src/main/java/java/lang/dongtai/SpyDispatcher.java +++ b/dongtai-spy/src/main/java/java/lang/dongtai/SpyDispatcher.java @@ -102,14 +102,14 @@ public interface SpyDispatcher { * * @since 1.3.1 */ - void enterPropagator(); + void enterPropagator(String signature); /** * mark for leave Source Entry Point * * @since 1.3.1 */ - void leavePropagator(); + void leavePropagator(String signature); /** * Determines whether it is a layer 1 Propagator entry @@ -117,7 +117,7 @@ public interface SpyDispatcher { * @return true if is a layer 1 Propagator entry; else false * @since 1.3.1 */ - boolean isFirstLevelPropagator(); + boolean isFirstLevelPropagator(String signature); /** * mark for enter Sink Entry Point