From ce508b243d6d1adf166cd8eba92a7b7d6dbe3a74 Mon Sep 17 00:00:00 2001 From: lostsnow Date: Mon, 15 Aug 2022 16:51:44 +0800 Subject: [PATCH 01/19] add taint range subset --- .../handler/hookpoint/vulscan/TaintRange.java | 133 +++++++++++++++ .../hookpoint/vulscan/TaintRanges.java | 153 ++++++++++++++++++ .../hookpoint/vulscan/TaintRangesBuilder.java | 108 +++++++++++++ .../handler/TaintRangeBuilderAppendTest.java | 87 ++++++++++ .../handler/TaintRangeBuilderKeepTest.java | 36 +++++ .../handler/TaintRangeBuilderSubsetTest.java | 96 +++++++++++ .../iast/core/handler/TaintRangeTest.java | 57 +++++++ .../iast/core/handler/TaintRangesTest.java | 107 ++++++++++++ 8 files changed, 777 insertions(+) create mode 100644 dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/TaintRange.java create mode 100644 dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/TaintRanges.java create mode 100644 dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/TaintRangesBuilder.java create mode 100644 dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangeBuilderAppendTest.java create mode 100644 dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangeBuilderKeepTest.java create mode 100644 dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangeBuilderSubsetTest.java create mode 100644 dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangeTest.java create mode 100644 dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangesTest.java diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/TaintRange.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/TaintRange.java new file mode 100644 index 000000000..977f0cace --- /dev/null +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/TaintRange.java @@ -0,0 +1,133 @@ +package io.dongtai.iast.core.handler.hookpoint.vulscan; + +public class TaintRange { + public static final String UNTRUSTED = "untrusted"; + + private String name; + public int start; + public int stop; + + public enum RangeRelation { + BELOW, + LOW_SPAN, + WITHIN, + CONTAIN, + HIGH_SPAN, + ABOVE + } + + public TaintRange(int start, int stop) { + this(UNTRUSTED, start, stop); + } + + public TaintRange(String name, int start, int stop) { + if (stop <= start) { + throw new RuntimeException("invalid taint range: " + name + ", stop: " + stop + " must greater than start: " + start); + } + this.name = name; + this.start = start; + this.stop = stop; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public int getStart() { + return this.start; + } + + public void setStart(int start) { + if (start < 0) { + throw new RuntimeException("invalid taint range: " + name + ", start:" + start + " must greater than 0"); + } + this.start = start; + } + + public int getStop() { + return this.stop; + } + + public void setStop(int stop) { + if (stop <= this.start) { + throw new RuntimeException("invalid taint range: " + name + ", stop: " + stop + " must greater than start: " + this.start); + } + this.stop = stop; + } + + public int width() { + return this.stop - this.start; + } + + public TaintRange clone() { + try { + return new TaintRange(this.name, this.start, this.stop); + } catch (RuntimeException e) { + return null; + } + } + + public boolean overlaps(TaintRange range) { + return range.name.equals(this.name) && this.start <= range.stop && range.start <= this.stop; + } + + /** + * merge when two taint range overlaps + * @param range TaintRange + */ + public void merge(TaintRange range) { + if (range.start < this.start) { + this.start = range.start; + } + if (range.stop > this.stop) { + this.stop = range.stop; + } + } + + public RangeRelation compareRange(int low, int high) { + if (high <= low) { + throw new RuntimeException("invalid compare, high: " + high + " must greater than low: " + low); + } + + if (this.start < low && this.stop <= low) { + // |-----| + // |------| + // |------| + return RangeRelation.BELOW; + } else if (this.start < low && this.stop <= high) { + // |----------| + // |-------------| + // |------| + return RangeRelation.LOW_SPAN; + } else if (this.start < low) { + // |-------------------| + // |------| + return RangeRelation.CONTAIN; + } else if (this.start < high && this.stop <= high) { + // |----| + // |-----| + // |-----| + // |------| + // |------| + return RangeRelation.WITHIN; + } else if (this.start < high) { + // |------| + // |----------| + // |------| + return RangeRelation.HIGH_SPAN; + } else { + // |------| + // |------| + // |------| + return RangeRelation.ABOVE; + } + } + + public String toString() { + return this.name + "(" + this.start + "," + this.stop + ")"; + } +} diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/TaintRanges.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/TaintRanges.java new file mode 100644 index 000000000..d632943be --- /dev/null +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/TaintRanges.java @@ -0,0 +1,153 @@ +package io.dongtai.iast.core.handler.hookpoint.vulscan; + +import java.util.*; + +public class TaintRanges { + private ArrayList taintRanges; + + public TaintRanges() { + this.taintRanges = new ArrayList(); + } + + public TaintRanges(ArrayList taintRanges) { + this.taintRanges = taintRanges; + } + + public TaintRanges(TaintRange ...taintRanges) { + this.taintRanges = new ArrayList(Arrays.asList(taintRanges)); + } + + public ArrayList getTaintRanges() { + return this.taintRanges; + } + + public void add(TaintRange taintRange) { + this.taintRanges.add(taintRange); + } + + public void addAll(TaintRanges taintRanges) { + if (taintRanges != null) { + this.taintRanges.addAll(taintRanges.getTaintRanges()); + } + } + + public void shift(int i) { + for (TaintRange taintRange : this.taintRanges) { + if (taintRange.start + i < 0 || taintRange.stop + i < 0) { + throw new RuntimeException("taint range shift range into negative value: " + i + ", " + toString()); + } + taintRange.start += i; + taintRange.stop += i; + } + } + + public void trim(int start, int end) { + if (start < 0) { + throw new RuntimeException("taint range trim invalid range start: " + start); + } + if (end < start) { + throw new RuntimeException("taint range trim invalid range stop: " + end + ", start: " + start); + } + if (end == start) { + this.taintRanges.clear(); + return; + } + + Iterator it = this.taintRanges.iterator(); + while (it.hasNext()) { + TaintRange next = it.next(); + switch (next.compareRange(start, end)) { + case BELOW: + case ABOVE: + it.remove(); + break; + case LOW_SPAN: + next.start = 0; + next.stop -= start; + break; + case WITHIN: + next.start -= start; + next.stop -= start; + break; + case CONTAIN: + next.start = 0; + next.stop = end - start; + break; + case HIGH_SPAN: + next.start -= start; + next.stop = end - start; + break; + default: + break; + } + } + } + + public TaintRanges clone() { + TaintRanges taintRanges = new TaintRanges(); + int size = this.taintRanges.size(); + for (int i = 0; i < size; i++) { + taintRanges.taintRanges.add(this.taintRanges.get(i).clone()); + } + return taintRanges; + } + + public void clear(int start, int stop) { + if (start < 0 || start > stop) { + throw new RuntimeException("taint range clear invalid range " + start + " to " + stop + " on " + toString()); + } + Iterator it = this.taintRanges.iterator(); + TaintRange taintRange = null; + while (it.hasNext()) { + TaintRange next2, next1 = it.next(); + switch (next1.compareRange(start, stop)) { + case LOW_SPAN: + next1.stop = start; + break; + case WITHIN: + it.remove(); + break; + case CONTAIN: + next2 = next1.clone(); + next1.stop = start; + next2.start = stop; + taintRange = next2; + break; + case HIGH_SPAN: + next1.start = stop; + break; + default: + } + } + if (taintRange != null) { + add(taintRange); + } + } + + public void merge() { + if (this.taintRanges.size() <= 1) { + return; + } + + for (int i = this.taintRanges.size() - 1; i >= 0; i--) { + TaintRange range1 = this.taintRanges.get(i); + for (int j = this.taintRanges.size() - 1; j >= 0; j--) { + if (j == i) { + continue; + } + TaintRange range2 = this.taintRanges.get(j); + if (range1.overlaps(range2)) { + range1.merge(range2); + this.taintRanges.remove(j); + if (i > this.taintRanges.size() - 1) { + i = this.taintRanges.size(); + } + } + } + } + } + + public String toString() { + return "Taints:" + this.taintRanges; + } +} diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/TaintRangesBuilder.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/TaintRangesBuilder.java new file mode 100644 index 000000000..f88be41f9 --- /dev/null +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/TaintRangesBuilder.java @@ -0,0 +1,108 @@ +package io.dongtai.iast.core.handler.hookpoint.vulscan; + +import java.io.ByteArrayOutputStream; +import java.io.StringWriter; + +public class TaintRangesBuilder { + public void keep(TaintRanges taintRanges, Object target, int argC, TaintRanges tgtTaintRanges) { + if (argC == 0) { + int length = this.getLength(target); + if (length > 0) { + for (TaintRange taintRange : tgtTaintRanges.getTaintRanges()) { + if (taintRange.getStart() < length && taintRange.getStop() > length) { + taintRange.setStop(length); + } + taintRanges.add(taintRange); + } + return; + } + taintRanges.addAll(tgtTaintRanges); + } + } + + public void append(TaintRanges taintRanges, Object target, TaintRanges srcTaintRanges, + Object source, TaintRanges tgtTaintRanges, int p1, int p2, int argC) { + int length = this.getLength(target); + switch (argC) { + case 0: + // src.append(tgt) + tgtTaintRanges.shift(length - this.getLength(source)); + taintRanges.addAll(srcTaintRanges); + taintRanges.addAll(tgtTaintRanges); + break; + case 2: + tgtTaintRanges.trim(p1, p2); + tgtTaintRanges.shift(length - (p2 - p1)); + taintRanges.addAll(srcTaintRanges); + taintRanges.addAll(tgtTaintRanges); + break; + case 3: + tgtTaintRanges.trim(p1, p1 + p2); + tgtTaintRanges.shift(length - p2); + taintRanges.addAll(srcTaintRanges); + taintRanges.addAll(tgtTaintRanges); + break; + default: + return; + } + taintRanges.merge(); + } + + public void subset(TaintRanges taintRanges, TaintRanges srcTaintRanges, Object source, TaintRanges tgtTaintRanges, int p1, int p2, int p3, int argC) { + int length = this.getLength(source); + switch (argC) { + case 1: + tgtTaintRanges.trim(p1, length); + taintRanges.addAll(tgtTaintRanges); + break; + case 2: + tgtTaintRanges.trim(p1, p2); + taintRanges.addAll(tgtTaintRanges); + break; + case 3: + srcTaintRanges.clear(p3, (p3 + p2) - p1); + tgtTaintRanges.trim(p1, p2); + tgtTaintRanges.shift(p3); + taintRanges.addAll(srcTaintRanges); + taintRanges.addAll(tgtTaintRanges); + break; + default: + break; + } + taintRanges.merge(); + } + + public int getLength(Object obj) { + if (obj == null) { + return 0; + } + + if (obj instanceof CharSequence) { + return ((CharSequence) obj).length(); + } else if (obj instanceof StringWriter) { + return ((StringWriter) obj).getBuffer().length(); + } else if (obj instanceof ByteArrayOutputStream) { + return ((ByteArrayOutputStream) obj).size(); + } else if (obj instanceof Character) { + return 1; + } else if (obj instanceof boolean[]) { + return ((boolean[]) obj).length; + } else if (obj instanceof byte[]) { + return ((byte[]) obj).length; + } else if (obj instanceof char[]) { + return ((char[]) obj).length; + } else if (obj instanceof short[]) { + return ((short[]) obj).length; + } else if (obj instanceof int[]) { + return ((int[]) obj).length; + } else if (obj instanceof float[]) { + return ((float[]) obj).length; + } else if (obj instanceof long[]) { + return ((long[]) obj).length; + } else if (obj instanceof double[]) { + return ((double[]) obj).length; + } else { + return (obj.getClass().getName() + "@" + Integer.toHexString(obj.hashCode())).length(); + } + } +} diff --git a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangeBuilderAppendTest.java b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangeBuilderAppendTest.java new file mode 100644 index 000000000..980132343 --- /dev/null +++ b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangeBuilderAppendTest.java @@ -0,0 +1,87 @@ +package io.dongtai.iast.core.handler; + +import io.dongtai.iast.core.handler.hookpoint.vulscan.*; +import org.junit.Assert; +import org.junit.Test; + +public class TaintRangeBuilderAppendTest { + @Test + public void testAppend() { + TaintRanges ts; + TaintRanges srcTs; + TaintRanges tgtTs; + TaintRangesBuilder tb = new TaintRangesBuilder(); + + ts = new TaintRanges(); + srcTs = new TaintRanges(); + tgtTs = new TaintRanges(new TaintRange(0,3)); + // "" + "foo" + tb.append(ts, new StringBuilder("foo"), srcTs, "foo", tgtTs, 0, 0, 0); + Assert.assertEquals("Taints:[untrusted(0,3)]", ts.toString()); + + ts = new TaintRanges(); + srcTs = new TaintRanges(); + tgtTs = new TaintRanges(new TaintRange(0,3)); + // "foo" + "bar" + tb.append(ts, new StringBuilder("foobar"), srcTs, "bar", tgtTs, 0, 0, 0); + Assert.assertEquals("Taints:[untrusted(3,6)]", ts.toString()); + + ts = new TaintRanges(); + srcTs = new TaintRanges(new TaintRange(0,1)); + tgtTs = new TaintRanges(new TaintRange(1,2)); + // "foo" + "bar" + tb.append(ts, new StringBuilder("foobar"), srcTs, "bar", tgtTs, 0, 0, 0); + Assert.assertEquals("Taints:[untrusted(0,1), untrusted(4,5)]", ts.toString()); + } + + @Test + public void testAppendStartStop() { + TaintRanges ts; + TaintRanges srcTs; + TaintRanges tgtTs; + TaintRangesBuilder tb = new TaintRangesBuilder(); + + ts = new TaintRanges(); + srcTs = new TaintRanges(); + tgtTs = new TaintRanges(new TaintRange(0,5)); + // StringBuilder("foo").append("1bar2", 1, 4) + tb.append(ts, new StringBuilder("foobar"), srcTs, "1bar2", tgtTs, 1, 4, 2); + Assert.assertEquals("Taints:[untrusted(3,6)]", ts.toString()); + + ts = new TaintRanges(); + srcTs = new TaintRanges(); + tgtTs = new TaintRanges(new TaintRange(0,3)); + // StringBuilder("foo").append("1bar2", 1, 4) + tb.append(ts, new StringBuilder("foobar"), srcTs, "1bar2", tgtTs, 1, 4, 2); + Assert.assertEquals("Taints:[untrusted(3,5)]", ts.toString()); + } + + @Test + public void testAppendStartLength() { + TaintRanges ts; + TaintRanges srcTs; + TaintRanges tgtTs; + TaintRangesBuilder tb = new TaintRangesBuilder(); + + ts = new TaintRanges(); + srcTs = new TaintRanges(); + tgtTs = new TaintRanges(new TaintRange(0,5)); + // StringBuilder("foo").append(char[]{"1bar2"}, 1, 3) + tb.append(ts, new StringBuilder("foobar"), srcTs, "1bar2", tgtTs, 1, 3, 3); + Assert.assertEquals("Taints:[untrusted(3,6)]", ts.toString()); + + ts = new TaintRanges(); + srcTs = new TaintRanges(); + tgtTs = new TaintRanges(new TaintRange(0,2)); + // StringBuilder("foo").append(char[]{"1bar2"}, 1, 3) + tb.append(ts, new StringBuilder("foobar"), srcTs, "1bar2", tgtTs, 1, 3, 3); + Assert.assertEquals("Taints:[untrusted(3,4)]", ts.toString()); + + ts = new TaintRanges(); + srcTs = new TaintRanges(new TaintRange(2,3)); + tgtTs = new TaintRanges(new TaintRange(0,2)); + // StringBuilder("foo").append(char[]{"1bar2"}, 1, 3) + tb.append(ts, new StringBuilder("foobar"), srcTs, "1bar2", tgtTs, 1, 3, 3); + Assert.assertEquals("Taints:[untrusted(2,4)]", ts.toString()); + } +} diff --git a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangeBuilderKeepTest.java b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangeBuilderKeepTest.java new file mode 100644 index 000000000..03642820f --- /dev/null +++ b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangeBuilderKeepTest.java @@ -0,0 +1,36 @@ +package io.dongtai.iast.core.handler; + +import io.dongtai.iast.core.handler.hookpoint.vulscan.*; +import org.junit.Assert; +import org.junit.Test; + +public class TaintRangeBuilderKeepTest { + @Test + public void testKeep() { + TaintRanges ts; + TaintRanges srcTs; + TaintRanges tgtTs; + TaintRangesBuilder tb = new TaintRangesBuilder(); + + ts = new TaintRanges(); + srcTs = new TaintRanges(); + tgtTs = new TaintRanges(new TaintRange(0,6)); + // new StringBuilder("foobar") + tb.keep(ts, new StringBuilder("foobar"), 0, tgtTs); + Assert.assertEquals("Taints:[untrusted(0,6)]", ts.toString()); + + ts = new TaintRanges(); + srcTs = new TaintRanges(); + tgtTs = new TaintRanges(new TaintRange(3,5)); + // new StringBuilder("foobar") + tb.keep(ts, new StringBuilder("foobar"), 0, tgtTs); + Assert.assertEquals("Taints:[untrusted(3,5)]", ts.toString()); + + ts = new TaintRanges(); + srcTs = new TaintRanges(); + tgtTs = new TaintRanges(new TaintRange(0,1), new TaintRange(3,5)); + // new StringBuilder("foobar") + tb.keep(ts, new StringBuilder("foobar"), 0, tgtTs); + Assert.assertEquals("Taints:[untrusted(0,1), untrusted(3,5)]", ts.toString()); + } +} diff --git a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangeBuilderSubsetTest.java b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangeBuilderSubsetTest.java new file mode 100644 index 000000000..ab5482154 --- /dev/null +++ b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangeBuilderSubsetTest.java @@ -0,0 +1,96 @@ +package io.dongtai.iast.core.handler; + +import io.dongtai.iast.core.handler.hookpoint.vulscan.*; +import org.junit.Assert; +import org.junit.Test; + +public class TaintRangeBuilderSubsetTest { + @Test + public void testSubsetStart() { + TaintRanges ts; + TaintRanges srcTs; + TaintRanges tgtTs; + TaintRangesBuilder tb = new TaintRangesBuilder(); + + ts = new TaintRanges(); + srcTs = new TaintRanges(); + tgtTs = new TaintRanges(new TaintRange(3,6)); + // new StringBuilder("foobar").substring(3) + tb.subset(ts, srcTs, new StringBuilder("foobar"), tgtTs, 3, 0, 0, 1); + Assert.assertEquals("Taints:[untrusted(0,3)]", ts.toString()); + + ts = new TaintRanges(); + srcTs = new TaintRanges(); + tgtTs = new TaintRanges(new TaintRange(3,6)); + // new StringBuilder("foobar").substring(2) + tb.subset(ts, srcTs, new StringBuilder("foobar"), tgtTs, 2, 0, 0, 1); + Assert.assertEquals("Taints:[untrusted(1,4)]", ts.toString()); + + ts = new TaintRanges(); + srcTs = new TaintRanges(); + tgtTs = new TaintRanges(new TaintRange(3,5)); + // new StringBuilder("foobar").substring(4) + tb.subset(ts, srcTs, new StringBuilder("foobar"), tgtTs, 4, 0, 0, 1); + Assert.assertEquals("Taints:[untrusted(0,1)]", ts.toString()); + } + + @Test + public void testSubsetStartStop() { + TaintRanges ts; + TaintRanges srcTs; + TaintRanges tgtTs; + TaintRangesBuilder tb = new TaintRangesBuilder(); + + ts = new TaintRanges(); + srcTs = new TaintRanges(); + tgtTs = new TaintRanges(new TaintRange(3,6)); + // new StringBuilder("foobarbaz").substring(3, 6) + tb.subset(ts, srcTs, new StringBuilder("foobarbaz"), tgtTs, 3, 6, 0, 2); + Assert.assertEquals("Taints:[untrusted(0,3)]", ts.toString()); + + ts = new TaintRanges(); + srcTs = new TaintRanges(); + tgtTs = new TaintRanges(new TaintRange(3,6)); + // new StringBuilder("foobarbaz").substring(2, 5) + tb.subset(ts, srcTs, new StringBuilder("foobarbaz"), tgtTs, 2, 5, 0, 2); + Assert.assertEquals("Taints:[untrusted(1,3)]", ts.toString()); + + ts = new TaintRanges(); + srcTs = new TaintRanges(); + tgtTs = new TaintRanges(new TaintRange(3,5)); + // new StringBuilder("foobarbaz").substring(4, 7) + tb.subset(ts, srcTs, new StringBuilder("foobarbaz"), tgtTs, 4, 7, 0, 2); + Assert.assertEquals("Taints:[untrusted(0,1)]", ts.toString()); + } + + @Test + public void testSubsetGetChars() { + TaintRanges ts; + TaintRanges srcTs; + TaintRanges tgtTs; + TaintRangesBuilder tb = new TaintRangesBuilder(); + + ts = new TaintRanges(); + srcTs = new TaintRanges(); + tgtTs = new TaintRanges(new TaintRange(1,3)); + // new StringBuilder("foo").getChars(0, 3, chars, 0) + tb.subset(ts, srcTs, new StringBuilder("foo"), tgtTs, 0, 3, 0, 3); + Assert.assertEquals("Taints:[untrusted(1,3)]", ts.toString()); + + ts = new TaintRanges(); + srcTs = new TaintRanges(new TaintRange(1,3)); + tgtTs = new TaintRanges(new TaintRange(2,5)); + // chars: "foo" + // new StringBuilder("11bar22").getChars(2, 5, chars, 3) + tb.subset(ts, srcTs, new StringBuilder("foo"), tgtTs, 2, 5, 3, 3); + Assert.assertEquals("Taints:[untrusted(1,6)]", ts.toString()); + + ts = new TaintRanges(); + srcTs = new TaintRanges(new TaintRange(1,2)); + tgtTs = new TaintRanges(new TaintRange(2,5)); + // chars: "foo" + // new StringBuilder("11bar22").getChars(2, 5, chars, 3) + tb.subset(ts, srcTs, new StringBuilder("foo"), tgtTs, 2, 5, 3, 3); + Assert.assertEquals("Taints:[untrusted(1,2), untrusted(3,6)]", ts.toString()); + } +} diff --git a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangeTest.java b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangeTest.java new file mode 100644 index 000000000..95da38819 --- /dev/null +++ b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangeTest.java @@ -0,0 +1,57 @@ +package io.dongtai.iast.core.handler; + +import io.dongtai.iast.core.handler.hookpoint.vulscan.TaintRange; +import org.junit.Assert; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +public class TaintRangeTest { + @Test + public void testOverlaps() { + TaintRange tr1; + TaintRange tr2; + tr1 = new TaintRange(5, 10); + + Map tests = new HashMap() {{ + put(new TaintRange(1, 4), false); + put(new TaintRange(1, 5), true); + put(new TaintRange(1, 11), true); + put(new TaintRange(9, 16), true); + put(new TaintRange(10, 16), true); + put(new TaintRange(11, 16), false); + }}; + for (Map.Entry entry : tests.entrySet()) { + tr2 = entry.getKey(); + Assert.assertEquals(tr1.toString() + " | " + tr2.toString(), entry.getValue(), tr1.overlaps(tr2)); + } + } + + @Test + public void testCompareRange() { + TaintRange base; + base = new TaintRange(5, 10); + + Map tests = new HashMap() {{ + put(new TaintRange(1, 4), TaintRange.RangeRelation.BELOW); + put(new TaintRange(1, 5), TaintRange.RangeRelation.BELOW); + put(new TaintRange(1, 6), TaintRange.RangeRelation.LOW_SPAN); + put(new TaintRange(1, 10), TaintRange.RangeRelation.LOW_SPAN); + put(new TaintRange(1, 11), TaintRange.RangeRelation.CONTAIN); + put(new TaintRange(5, 10), TaintRange.RangeRelation.WITHIN); + put(new TaintRange(5, 9), TaintRange.RangeRelation.WITHIN); + put(new TaintRange(6, 10), TaintRange.RangeRelation.WITHIN); + put(new TaintRange(6, 9), TaintRange.RangeRelation.WITHIN); + put(new TaintRange(5, 11), TaintRange.RangeRelation.HIGH_SPAN); + put(new TaintRange(6, 11), TaintRange.RangeRelation.HIGH_SPAN); + put(new TaintRange(10, 12), TaintRange.RangeRelation.ABOVE); + put(new TaintRange(11, 12), TaintRange.RangeRelation.ABOVE); + }}; + + for (Map.Entry entry : tests.entrySet()) { + TaintRange tr = entry.getKey(); + Assert.assertEquals(base.toString() + " | " + tr.toString(), entry.getValue(), tr.compareRange(base.start, base.stop)); + } + } +} diff --git a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangesTest.java b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangesTest.java new file mode 100644 index 000000000..20929b4f6 --- /dev/null +++ b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangesTest.java @@ -0,0 +1,107 @@ +package io.dongtai.iast.core.handler; + +import io.dongtai.iast.core.handler.hookpoint.vulscan.TaintRange; +import io.dongtai.iast.core.handler.hookpoint.vulscan.TaintRanges; +import org.junit.Assert; +import org.junit.Test; +import org.junit.function.ThrowingRunnable; + +import java.util.*; + +public class TaintRangesTest { + @Test + public void testShift() { + TaintRange tr1; + TaintRange tr2; + TaintRanges ts; + + tr1 = new TaintRange(5, 9); + tr2 = new TaintRange(13, 16); + ts = new TaintRanges(tr1, tr2); + ts.shift(3); + Assert.assertEquals(ts.toString(), "Taints:[untrusted(8,12), untrusted(16,19)]"); + + tr1 = new TaintRange(5, 9); + tr2 = new TaintRange(13, 16); + ts = new TaintRanges(tr1, tr2); + ts.shift(-3); + Assert.assertEquals(ts.toString(), "Taints:[untrusted(2,6), untrusted(10,13)]"); + + tr1 = new TaintRange(5, 9); + tr2 = new TaintRange(13, 16); + final TaintRanges fts = new TaintRanges(tr1, tr2); + Assert.assertThrows(RuntimeException.class, new ThrowingRunnable() { + @Override + public void run() { + fts.shift(-6); + } + }); + } + + @Test + public void testTrim() { + TaintRange tr; + TaintRanges ts; + + // base: TaintRange(5, 10) + Map, String> tests = new HashMap, String>() {{ + put(Arrays.asList(7, 7), "Taints:[]"); + // |---| + // |-| + put(Arrays.asList(3, 5), "Taints:[]"); + // |----| + // |----| + put(Arrays.asList(7, 12), "Taints:[untrusted(0,3)]"); + // |----| + // |----| + put(Arrays.asList(3, 8), "Taints:[untrusted(2,5)]"); + // |----| + // |------| + put(Arrays.asList(4, 11), "Taints:[untrusted(1,6)]"); + // |----| + // |-| + put(Arrays.asList(6, 8), "Taints:[untrusted(0,2)]"); + // |----| + // |---| + put(Arrays.asList(7, 12), "Taints:[untrusted(0,3)]"); + // |----| + // |-| + put(Arrays.asList(10, 12), "Taints:[]"); + }}; + + for (Map.Entry, String> entry : tests.entrySet()) { + tr = new TaintRange(5, 10); + ts = new TaintRanges(tr); + ts.trim(entry.getKey().get(0), entry.getKey().get(1)); + Assert.assertEquals(tr.toString() + " | " + entry.getKey().toString(), entry.getValue(), ts.toString()); + } + } + + @Test + public void testMerge() { + TaintRange tr1; + TaintRange tr2; + TaintRanges ts; + + tr1 = new TaintRange(5, 10); + Map tests = new HashMap() {{ + put(new TaintRange(1, 4), "Taints:[untrusted(5,10), untrusted(1,4)]"); + put(new TaintRange(1, 5), "Taints:[untrusted(1,10)]"); + put(new TaintRange(1, 7), "Taints:[untrusted(1,10)]"); + put(new TaintRange(1, 11), "Taints:[untrusted(1,11)]"); + put(new TaintRange(6, 7), "Taints:[untrusted(5,10)]"); + put(new TaintRange(6, 11), "Taints:[untrusted(5,11)]"); + put(new TaintRange(5, 15), "Taints:[untrusted(5,15)]"); + put(new TaintRange(10, 15), "Taints:[untrusted(5,15)]"); + put(new TaintRange(11, 15), "Taints:[untrusted(5,10), untrusted(11,15)]"); + }}; + + for (Map.Entry entry : tests.entrySet()) { + tr2 = entry.getKey(); + ts = new TaintRanges(tr1, tr2); + TaintRanges tsCopy = ts; + ts.merge(); + Assert.assertEquals(tsCopy.toString(), entry.getValue(), ts.toString()); + } + } +} From 1bb64c7e05bfe07a32adcd2b93048ded9d9974e9 Mon Sep 17 00:00:00 2001 From: lostsnow Date: Mon, 15 Aug 2022 16:55:57 +0800 Subject: [PATCH 02/19] change taint range dir --- .../hookpoint/vulscan/{ => taintrange}/TaintRange.java | 2 +- .../hookpoint/vulscan/{ => taintrange}/TaintRanges.java | 2 +- .../vulscan/{ => taintrange}/TaintRangesBuilder.java | 2 +- .../vulscan/taintrange}/TaintRangeBuilderAppendTest.java | 3 +-- .../vulscan/taintrange}/TaintRangeBuilderKeepTest.java | 3 +-- .../vulscan/taintrange}/TaintRangeBuilderSubsetTest.java | 3 +-- .../{ => hookpoint/vulscan/taintrange}/TaintRangeTest.java | 3 +-- .../{ => hookpoint/vulscan/taintrange}/TaintRangesTest.java | 4 +--- 8 files changed, 8 insertions(+), 14 deletions(-) rename dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/{ => taintrange}/TaintRange.java (98%) rename dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/{ => taintrange}/TaintRanges.java (98%) rename dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/{ => taintrange}/TaintRangesBuilder.java (98%) rename dongtai-core/src/test/java/io/dongtai/iast/core/handler/{ => hookpoint/vulscan/taintrange}/TaintRangeBuilderAppendTest.java (97%) rename dongtai-core/src/test/java/io/dongtai/iast/core/handler/{ => hookpoint/vulscan/taintrange}/TaintRangeBuilderKeepTest.java (92%) rename dongtai-core/src/test/java/io/dongtai/iast/core/handler/{ => hookpoint/vulscan/taintrange}/TaintRangeBuilderSubsetTest.java (97%) rename dongtai-core/src/test/java/io/dongtai/iast/core/handler/{ => hookpoint/vulscan/taintrange}/TaintRangeTest.java (95%) rename dongtai-core/src/test/java/io/dongtai/iast/core/handler/{ => hookpoint/vulscan/taintrange}/TaintRangesTest.java (95%) diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/TaintRange.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRange.java similarity index 98% rename from dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/TaintRange.java rename to dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRange.java index 977f0cace..f387ea5d7 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/TaintRange.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRange.java @@ -1,4 +1,4 @@ -package io.dongtai.iast.core.handler.hookpoint.vulscan; +package io.dongtai.iast.core.handler.hookpoint.vulscan.taintrange; public class TaintRange { public static final String UNTRUSTED = "untrusted"; diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/TaintRanges.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRanges.java similarity index 98% rename from dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/TaintRanges.java rename to dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRanges.java index d632943be..5ccc78f4c 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/TaintRanges.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRanges.java @@ -1,4 +1,4 @@ -package io.dongtai.iast.core.handler.hookpoint.vulscan; +package io.dongtai.iast.core.handler.hookpoint.vulscan.taintrange; import java.util.*; diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/TaintRangesBuilder.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesBuilder.java similarity index 98% rename from dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/TaintRangesBuilder.java rename to dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesBuilder.java index f88be41f9..70fc9247b 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/TaintRangesBuilder.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesBuilder.java @@ -1,4 +1,4 @@ -package io.dongtai.iast.core.handler.hookpoint.vulscan; +package io.dongtai.iast.core.handler.hookpoint.vulscan.taintrange; import java.io.ByteArrayOutputStream; import java.io.StringWriter; diff --git a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangeBuilderAppendTest.java b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderAppendTest.java similarity index 97% rename from dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangeBuilderAppendTest.java rename to dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderAppendTest.java index 980132343..ef2d79311 100644 --- a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangeBuilderAppendTest.java +++ b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderAppendTest.java @@ -1,6 +1,5 @@ -package io.dongtai.iast.core.handler; +package io.dongtai.iast.core.handler.hookpoint.vulscan.taintrange; -import io.dongtai.iast.core.handler.hookpoint.vulscan.*; import org.junit.Assert; import org.junit.Test; diff --git a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangeBuilderKeepTest.java b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderKeepTest.java similarity index 92% rename from dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangeBuilderKeepTest.java rename to dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderKeepTest.java index 03642820f..722cba187 100644 --- a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangeBuilderKeepTest.java +++ b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderKeepTest.java @@ -1,6 +1,5 @@ -package io.dongtai.iast.core.handler; +package io.dongtai.iast.core.handler.hookpoint.vulscan.taintrange; -import io.dongtai.iast.core.handler.hookpoint.vulscan.*; import org.junit.Assert; import org.junit.Test; diff --git a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangeBuilderSubsetTest.java b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderSubsetTest.java similarity index 97% rename from dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangeBuilderSubsetTest.java rename to dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderSubsetTest.java index ab5482154..a70dad20d 100644 --- a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangeBuilderSubsetTest.java +++ b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderSubsetTest.java @@ -1,6 +1,5 @@ -package io.dongtai.iast.core.handler; +package io.dongtai.iast.core.handler.hookpoint.vulscan.taintrange; -import io.dongtai.iast.core.handler.hookpoint.vulscan.*; import org.junit.Assert; import org.junit.Test; diff --git a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangeTest.java b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeTest.java similarity index 95% rename from dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangeTest.java rename to dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeTest.java index 95da38819..4bad769cc 100644 --- a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangeTest.java +++ b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeTest.java @@ -1,6 +1,5 @@ -package io.dongtai.iast.core.handler; +package io.dongtai.iast.core.handler.hookpoint.vulscan.taintrange; -import io.dongtai.iast.core.handler.hookpoint.vulscan.TaintRange; import org.junit.Assert; import org.junit.Test; diff --git a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangesTest.java b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesTest.java similarity index 95% rename from dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangesTest.java rename to dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesTest.java index 20929b4f6..905503e41 100644 --- a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/TaintRangesTest.java +++ b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesTest.java @@ -1,7 +1,5 @@ -package io.dongtai.iast.core.handler; +package io.dongtai.iast.core.handler.hookpoint.vulscan.taintrange; -import io.dongtai.iast.core.handler.hookpoint.vulscan.TaintRange; -import io.dongtai.iast.core.handler.hookpoint.vulscan.TaintRanges; import org.junit.Assert; import org.junit.Test; import org.junit.function.ThrowingRunnable; From 361c09fb1bb4971ff1a14739e2a8a66573ebe251 Mon Sep 17 00:00:00 2001 From: lostsnow Date: Tue, 16 Aug 2022 18:21:01 +0800 Subject: [PATCH 03/19] add taint range insert --- .../vulscan/taintrange/TaintRanges.java | 77 +++++++++++++++--- .../taintrange/TaintRangesBuilder.java | 29 ++++++- .../TaintRangeBuilderAppendTest.java | 50 ++++++------ .../TaintRangeBuilderInsertTest.java | 78 +++++++++++++++++++ .../taintrange/TaintRangeBuilderKeepTest.java | 25 +++--- .../TaintRangeBuilderSubsetTest.java | 44 +++++------ .../vulscan/taintrange/TaintRangesTest.java | 63 +++++++++++++++ 7 files changed, 297 insertions(+), 69 deletions(-) create mode 100644 dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderInsertTest.java diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRanges.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRanges.java index 5ccc78f4c..d4028335f 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRanges.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRanges.java @@ -31,10 +31,19 @@ public void addAll(TaintRanges taintRanges) { } } + public TaintRanges clone() { + TaintRanges taintRanges = new TaintRanges(); + int size = this.taintRanges.size(); + for (int i = 0; i < size; i++) { + taintRanges.taintRanges.add(this.taintRanges.get(i).clone()); + } + return taintRanges; + } + public void shift(int i) { for (TaintRange taintRange : this.taintRanges) { if (taintRange.start + i < 0 || taintRange.stop + i < 0) { - throw new RuntimeException("taint range shift range into negative value: " + i + ", " + toString()); + throw new RuntimeException("taint range shift range into negative value: " + i); } taintRange.start += i; taintRange.stop += i; @@ -43,10 +52,10 @@ public void shift(int i) { public void trim(int start, int end) { if (start < 0) { - throw new RuntimeException("taint range trim invalid range start: " + start); + throw new RuntimeException("taint range trim invalid start: " + start); } if (end < start) { - throw new RuntimeException("taint range trim invalid range stop: " + end + ", start: " + start); + throw new RuntimeException("taint range trim invalid stop: " + end + " < start: " + start); } if (end == start) { this.taintRanges.clear(); @@ -83,18 +92,64 @@ public void trim(int start, int end) { } } - public TaintRanges clone() { - TaintRanges taintRanges = new TaintRanges(); - int size = this.taintRanges.size(); - for (int i = 0; i < size; i++) { - taintRanges.taintRanges.add(this.taintRanges.get(i).clone()); + public void split(int start, int stop) { + if (start < 0) { + throw new RuntimeException("taint range split invalid start: " + start); + } + if (stop < start) { + throw new RuntimeException("taint range split invalid stop: " + stop + " < start:" + start); + } + if (stop != start) { + int width = stop - start; + List newTaintRange = new ArrayList(); + for (TaintRange taintRange : this.taintRanges) { + if (start <= taintRange.stop) { + if (start > taintRange.start && start < taintRange.stop) { + newTaintRange.add(new TaintRange(taintRange.getName(), stop, taintRange.stop + width)); + taintRange.stop = start; + } else if (start <= taintRange.start) { + taintRange.start += width; + taintRange.stop += width; + } + } + } + this.taintRanges.addAll(newTaintRange); + } + } + + public void subRange(int start, int stop) { + if (start < 0) { + throw new RuntimeException("taint range subRange invalid start: " + start); + } + if (stop < start) { + throw new RuntimeException("taint range subRange invalid stop: " + stop + " < start:" + start); + } + if (stop == start) { + this.taintRanges.clear(); + return; + } + Iterator it = this.taintRanges.iterator(); + while (it.hasNext()) { + TaintRange next = it.next(); + switch (next.compareRange(start, stop)) { + case BELOW: + case ABOVE: + it.remove(); + break; + default: + next.start = Math.max(next.start, start); + next.stop = Math.min(next.stop, stop); + break; + } } - return taintRanges; } public void clear(int start, int stop) { - if (start < 0 || start > stop) { - throw new RuntimeException("taint range clear invalid range " + start + " to " + stop + " on " + toString()); + if (start < 0) { + throw new RuntimeException("taint range clear invalid start: " + start); + } + if (stop <= start) { + throw new RuntimeException("taint range clear invalid stop: " + stop + " <= start:" + start); } Iterator it = this.taintRanges.iterator(); TaintRange taintRange = null; diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesBuilder.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesBuilder.java index 70fc9247b..8b5f8bf91 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesBuilder.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesBuilder.java @@ -14,9 +14,11 @@ public void keep(TaintRanges taintRanges, Object target, int argC, TaintRanges t } taintRanges.add(taintRange); } - return; + } else { + taintRanges.addAll(tgtTaintRanges); } - taintRanges.addAll(tgtTaintRanges); + + taintRanges.merge(); } } @@ -67,7 +69,30 @@ public void subset(TaintRanges taintRanges, TaintRanges srcTaintRanges, Object s taintRanges.addAll(tgtTaintRanges); break; default: + return; + } + taintRanges.merge(); + } + + public void insert(TaintRanges taintRanges, TaintRanges srcTaintRanges, Object source, TaintRanges tgtTaintRanges, int p1, int p2, int p3, int argC) { + int length = this.getLength(source); + switch (argC) { + case 1: + tgtTaintRanges.shift(p1); + srcTaintRanges.split(p1, length + p1); + taintRanges.addAll(srcTaintRanges); + taintRanges.addAll(tgtTaintRanges); break; + case 3: + length = p3 - p2; + tgtTaintRanges.subRange(p2, p3); + tgtTaintRanges.shift(p1 - p2); + srcTaintRanges.split(p1, length + p1); + taintRanges.addAll(srcTaintRanges); + taintRanges.addAll(tgtTaintRanges); + break; + default: + return; } taintRanges.merge(); } diff --git a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderAppendTest.java b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderAppendTest.java index ef2d79311..9002b760a 100644 --- a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderAppendTest.java +++ b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderAppendTest.java @@ -13,23 +13,23 @@ public void testAppend() { ts = new TaintRanges(); srcTs = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(0,3)); - // "" + "foo" - tb.append(ts, new StringBuilder("foo"), srcTs, "foo", tgtTs, 0, 0, 0); + tgtTs = new TaintRanges(new TaintRange(0, 3)); + // "" + "FOO" + tb.append(ts, new StringBuilder("FOO"), srcTs, "FOO", tgtTs, 0, 0, 0); Assert.assertEquals("Taints:[untrusted(0,3)]", ts.toString()); ts = new TaintRanges(); srcTs = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(0,3)); + tgtTs = new TaintRanges(new TaintRange(0, 3)); // "foo" + "bar" - tb.append(ts, new StringBuilder("foobar"), srcTs, "bar", tgtTs, 0, 0, 0); + tb.append(ts, new StringBuilder("fooBAR"), srcTs, "BAR", tgtTs, 0, 0, 0); Assert.assertEquals("Taints:[untrusted(3,6)]", ts.toString()); ts = new TaintRanges(); - srcTs = new TaintRanges(new TaintRange(0,1)); - tgtTs = new TaintRanges(new TaintRange(1,2)); - // "foo" + "bar" - tb.append(ts, new StringBuilder("foobar"), srcTs, "bar", tgtTs, 0, 0, 0); + srcTs = new TaintRanges(new TaintRange(0, 1)); + tgtTs = new TaintRanges(new TaintRange(1, 2)); + // "Foo" + "bAr" + tb.append(ts, new StringBuilder("FoobAr"), srcTs, "bAr", tgtTs, 0, 0, 0); Assert.assertEquals("Taints:[untrusted(0,1), untrusted(4,5)]", ts.toString()); } @@ -42,16 +42,16 @@ public void testAppendStartStop() { ts = new TaintRanges(); srcTs = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(0,5)); - // StringBuilder("foo").append("1bar2", 1, 4) - tb.append(ts, new StringBuilder("foobar"), srcTs, "1bar2", tgtTs, 1, 4, 2); + tgtTs = new TaintRanges(new TaintRange(0, 5)); + // StringBuilder("foo").append("ZBARZ", 1, 4) + tb.append(ts, new StringBuilder("fooBAR"), srcTs, "ZBARZ", tgtTs, 1, 4, 2); Assert.assertEquals("Taints:[untrusted(3,6)]", ts.toString()); ts = new TaintRanges(); srcTs = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(0,3)); - // StringBuilder("foo").append("1bar2", 1, 4) - tb.append(ts, new StringBuilder("foobar"), srcTs, "1bar2", tgtTs, 1, 4, 2); + tgtTs = new TaintRanges(new TaintRange(0, 3)); + // StringBuilder("foo").append("ZBArz", 1, 4) + tb.append(ts, new StringBuilder("fooBAr"), srcTs, "ZBArz", tgtTs, 1, 4, 2); Assert.assertEquals("Taints:[untrusted(3,5)]", ts.toString()); } @@ -64,23 +64,23 @@ public void testAppendStartLength() { ts = new TaintRanges(); srcTs = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(0,5)); - // StringBuilder("foo").append(char[]{"1bar2"}, 1, 3) - tb.append(ts, new StringBuilder("foobar"), srcTs, "1bar2", tgtTs, 1, 3, 3); + tgtTs = new TaintRanges(new TaintRange(0, 5)); + // StringBuilder("foo").append(char[]{"ZBARZ"}, 1, 3) + tb.append(ts, new StringBuilder("fooBAR"), srcTs, "ZBARZ", tgtTs, 1, 3, 3); Assert.assertEquals("Taints:[untrusted(3,6)]", ts.toString()); ts = new TaintRanges(); srcTs = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(0,2)); - // StringBuilder("foo").append(char[]{"1bar2"}, 1, 3) - tb.append(ts, new StringBuilder("foobar"), srcTs, "1bar2", tgtTs, 1, 3, 3); + tgtTs = new TaintRanges(new TaintRange(0, 2)); + // StringBuilder("foo").append(char[]{"ZBarz"}, 1, 3) + tb.append(ts, new StringBuilder("fooBar"), srcTs, "ZBarz", tgtTs, 1, 3, 3); Assert.assertEquals("Taints:[untrusted(3,4)]", ts.toString()); ts = new TaintRanges(); - srcTs = new TaintRanges(new TaintRange(2,3)); - tgtTs = new TaintRanges(new TaintRange(0,2)); - // StringBuilder("foo").append(char[]{"1bar2"}, 1, 3) - tb.append(ts, new StringBuilder("foobar"), srcTs, "1bar2", tgtTs, 1, 3, 3); + srcTs = new TaintRanges(new TaintRange(2, 3)); + tgtTs = new TaintRanges(new TaintRange(0, 2)); + // StringBuilder("foO").append(char[]{"ZBarz"}, 1, 3) + tb.append(ts, new StringBuilder("foOBar"), srcTs, "ZBarz", tgtTs, 1, 3, 3); Assert.assertEquals("Taints:[untrusted(2,4)]", ts.toString()); } } diff --git a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderInsertTest.java b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderInsertTest.java new file mode 100644 index 000000000..4eb82f82a --- /dev/null +++ b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderInsertTest.java @@ -0,0 +1,78 @@ +package io.dongtai.iast.core.handler.hookpoint.vulscan.taintrange; + +import org.junit.Assert; +import org.junit.Test; + +public class TaintRangeBuilderInsertTest { + @Test + public void testInsert() { + TaintRanges ts; + TaintRanges srcTs; + TaintRanges tgtTs; + TaintRangesBuilder tb = new TaintRangesBuilder(); + + ts = new TaintRanges(); + srcTs = new TaintRanges(); + tgtTs = new TaintRanges(new TaintRange(0,2)); + // new StringBuilder("fbar").insert(1, "OO") // fOObar + tb.insert(ts, srcTs, new StringBuilder("OO"), tgtTs, 1, 0, 0, 1); + Assert.assertEquals("Taints:[untrusted(1,3)]", ts.toString()); + + ts = new TaintRanges(); + srcTs = new TaintRanges(new TaintRange(2,3)); + tgtTs = new TaintRanges(new TaintRange(0,2)); + // new StringBuilder("fbAr").insert(1, "OO") // fOObAr + tb.insert(ts, srcTs, new StringBuilder("OO"), tgtTs, 1, 0, 0, 1); + Assert.assertEquals("Taints:[untrusted(4,5), untrusted(1,3)]", ts.toString()); + + ts = new TaintRanges(); + srcTs = new TaintRanges(new TaintRange(0,1), new TaintRange(2,3)); + tgtTs = new TaintRanges(new TaintRange(1,2)); + // new StringBuilder("FbAr").insert(1, "oO") // FoObAr + tb.insert(ts, srcTs, new StringBuilder("oO"), tgtTs, 1, 0, 0, 1); + Assert.assertEquals("Taints:[untrusted(0,1), untrusted(4,5), untrusted(2,3)]", ts.toString()); + } + + @Test + public void testInsertRange() { + TaintRanges ts; + TaintRanges srcTs; + TaintRanges tgtTs; + TaintRangesBuilder tb = new TaintRangesBuilder(); + + ts = new TaintRanges(); + srcTs = new TaintRanges(); + tgtTs = new TaintRanges(new TaintRange(2,4)); + // new StringBuilder("foar").insert(2, "zzOBzz", 2, 4) // foOBar + tb.insert(ts, srcTs, new StringBuilder("zzOBzz"), tgtTs, 2, 2, 4, 3); + Assert.assertEquals("Taints:[untrusted(2,4)]", ts.toString()); + + ts = new TaintRanges(); + srcTs = new TaintRanges(new TaintRange(0,1)); + tgtTs = new TaintRanges(new TaintRange(2,4)); + // new StringBuilder("Foar").insert(2, "zzOBzz", 2, 4) // FoOBar + tb.insert(ts, srcTs, new StringBuilder("zzOBzz"), tgtTs, 2, 2, 4, 3); + Assert.assertEquals("Taints:[untrusted(0,1), untrusted(2,4)]", ts.toString()); + + ts = new TaintRanges(); + srcTs = new TaintRanges(new TaintRange(3,4)); + tgtTs = new TaintRanges(new TaintRange(2,4)); + // new StringBuilder("foaR").insert(2, "zzOBzz", 2, 4) // foOBaR + tb.insert(ts, srcTs, new StringBuilder("zzOBzz"), tgtTs, 2, 2, 4, 3); + Assert.assertEquals("Taints:[untrusted(5,6), untrusted(2,4)]", ts.toString()); + + ts = new TaintRanges(); + srcTs = new TaintRanges(new TaintRange(2,3)); + tgtTs = new TaintRanges(new TaintRange(2,4)); + // new StringBuilder("foAr").insert(2, "zzOBzz", 2, 4) // foOBAr + tb.insert(ts, srcTs, new StringBuilder("zzOBzz"), tgtTs, 2, 2, 4, 3); + Assert.assertEquals("Taints:[untrusted(2,5)]", ts.toString()); + + ts = new TaintRanges(); + srcTs = new TaintRanges(new TaintRange(1,3)); + tgtTs = new TaintRanges(new TaintRange(3,4)); + // new StringBuilder("fOAr").insert(2, "zzoBzz", 2, 4) // fOoBAr + tb.insert(ts, srcTs, new StringBuilder("zzoBzz"), tgtTs, 2, 2, 4, 3); + Assert.assertEquals("Taints:[untrusted(1,2), untrusted(3,5)]", ts.toString()); + } +} diff --git a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderKeepTest.java b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderKeepTest.java index 722cba187..82dcce925 100644 --- a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderKeepTest.java +++ b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderKeepTest.java @@ -13,23 +13,30 @@ public void testKeep() { ts = new TaintRanges(); srcTs = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(0,6)); - // new StringBuilder("foobar") - tb.keep(ts, new StringBuilder("foobar"), 0, tgtTs); + tgtTs = new TaintRanges(new TaintRange(0, 6)); + // new StringBuilder("FOOBAR") + tb.keep(ts, new StringBuilder("FOOBAR"), 0, tgtTs); Assert.assertEquals("Taints:[untrusted(0,6)]", ts.toString()); ts = new TaintRanges(); srcTs = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(3,5)); - // new StringBuilder("foobar") - tb.keep(ts, new StringBuilder("foobar"), 0, tgtTs); + tgtTs = new TaintRanges(new TaintRange(3, 5)); + // new StringBuilder("fooBAr") + tb.keep(ts, new StringBuilder("fooBAr"), 0, tgtTs); Assert.assertEquals("Taints:[untrusted(3,5)]", ts.toString()); ts = new TaintRanges(); srcTs = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(0,1), new TaintRange(3,5)); - // new StringBuilder("foobar") - tb.keep(ts, new StringBuilder("foobar"), 0, tgtTs); + tgtTs = new TaintRanges(new TaintRange(0, 1), new TaintRange(3, 5)); + // new StringBuilder("FooBAr") + tb.keep(ts, new StringBuilder("FooBAr"), 0, tgtTs); Assert.assertEquals("Taints:[untrusted(0,1), untrusted(3,5)]", ts.toString()); + + ts = new TaintRanges(); + srcTs = new TaintRanges(); + tgtTs = new TaintRanges(new TaintRange(1, 3), new TaintRange(3, 5)); + // new StringBuilder("fOOBAr") + tb.keep(ts, new StringBuilder("fOOBAr"), 0, tgtTs); + Assert.assertEquals("Taints:[untrusted(1,5)]", ts.toString()); } } diff --git a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderSubsetTest.java b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderSubsetTest.java index a70dad20d..44d34276c 100644 --- a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderSubsetTest.java +++ b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderSubsetTest.java @@ -13,23 +13,23 @@ public void testSubsetStart() { ts = new TaintRanges(); srcTs = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(3,6)); - // new StringBuilder("foobar").substring(3) - tb.subset(ts, srcTs, new StringBuilder("foobar"), tgtTs, 3, 0, 0, 1); + tgtTs = new TaintRanges(new TaintRange(3, 6)); + // new StringBuilder("fooBAR").substring(3) // BAR + tb.subset(ts, srcTs, new StringBuilder("fooBAR"), tgtTs, 3, 0, 0, 1); Assert.assertEquals("Taints:[untrusted(0,3)]", ts.toString()); ts = new TaintRanges(); srcTs = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(3,6)); - // new StringBuilder("foobar").substring(2) - tb.subset(ts, srcTs, new StringBuilder("foobar"), tgtTs, 2, 0, 0, 1); + tgtTs = new TaintRanges(new TaintRange(3, 6)); + // new StringBuilder("fooBAR").substring(2) // oBAR + tb.subset(ts, srcTs, new StringBuilder("fooBAR"), tgtTs, 2, 0, 0, 1); Assert.assertEquals("Taints:[untrusted(1,4)]", ts.toString()); ts = new TaintRanges(); srcTs = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(3,5)); - // new StringBuilder("foobar").substring(4) - tb.subset(ts, srcTs, new StringBuilder("foobar"), tgtTs, 4, 0, 0, 1); + tgtTs = new TaintRanges(new TaintRange(3, 5)); + // new StringBuilder("fooBAr").substring(4) // Ar + tb.subset(ts, srcTs, new StringBuilder("fooBAr"), tgtTs, 4, 0, 0, 1); Assert.assertEquals("Taints:[untrusted(0,1)]", ts.toString()); } @@ -43,21 +43,21 @@ public void testSubsetStartStop() { ts = new TaintRanges(); srcTs = new TaintRanges(); tgtTs = new TaintRanges(new TaintRange(3,6)); - // new StringBuilder("foobarbaz").substring(3, 6) + // new StringBuilder("fooBARbaz").substring(3, 6) // BAR tb.subset(ts, srcTs, new StringBuilder("foobarbaz"), tgtTs, 3, 6, 0, 2); Assert.assertEquals("Taints:[untrusted(0,3)]", ts.toString()); ts = new TaintRanges(); srcTs = new TaintRanges(); tgtTs = new TaintRanges(new TaintRange(3,6)); - // new StringBuilder("foobarbaz").substring(2, 5) + // new StringBuilder("fooBARbaz").substring(2, 5) // oBA tb.subset(ts, srcTs, new StringBuilder("foobarbaz"), tgtTs, 2, 5, 0, 2); Assert.assertEquals("Taints:[untrusted(1,3)]", ts.toString()); ts = new TaintRanges(); srcTs = new TaintRanges(); tgtTs = new TaintRanges(new TaintRange(3,5)); - // new StringBuilder("foobarbaz").substring(4, 7) + // new StringBuilder("fooBArbaz").substring(4, 7) // Arb tb.subset(ts, srcTs, new StringBuilder("foobarbaz"), tgtTs, 4, 7, 0, 2); Assert.assertEquals("Taints:[untrusted(0,1)]", ts.toString()); } @@ -71,24 +71,24 @@ public void testSubsetGetChars() { ts = new TaintRanges(); srcTs = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(1,3)); - // new StringBuilder("foo").getChars(0, 3, chars, 0) + tgtTs = new TaintRanges(new TaintRange(1, 3)); + // new StringBuilder("fOO").getChars(0, 3, chars, 0) // fOO tb.subset(ts, srcTs, new StringBuilder("foo"), tgtTs, 0, 3, 0, 3); Assert.assertEquals("Taints:[untrusted(1,3)]", ts.toString()); ts = new TaintRanges(); - srcTs = new TaintRanges(new TaintRange(1,3)); - tgtTs = new TaintRanges(new TaintRange(2,5)); - // chars: "foo" - // new StringBuilder("11bar22").getChars(2, 5, chars, 3) + srcTs = new TaintRanges(new TaintRange(1, 3)); + tgtTs = new TaintRanges(new TaintRange(2, 5)); + // chars: "fOO" + // new StringBuilder("zzBARzz").getChars(2, 5, chars, 3) // fOOBAR tb.subset(ts, srcTs, new StringBuilder("foo"), tgtTs, 2, 5, 3, 3); Assert.assertEquals("Taints:[untrusted(1,6)]", ts.toString()); ts = new TaintRanges(); - srcTs = new TaintRanges(new TaintRange(1,2)); - tgtTs = new TaintRanges(new TaintRange(2,5)); - // chars: "foo" - // new StringBuilder("11bar22").getChars(2, 5, chars, 3) + srcTs = new TaintRanges(new TaintRange(1, 2)); + tgtTs = new TaintRanges(new TaintRange(2, 5)); + // chars: "fOo" + // new StringBuilder("zzBARzz").getChars(2, 5, chars, 3) // fOoBAR tb.subset(ts, srcTs, new StringBuilder("foo"), tgtTs, 2, 5, 3, 3); Assert.assertEquals("Taints:[untrusted(1,2), untrusted(3,6)]", ts.toString()); } diff --git a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesTest.java b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesTest.java index 905503e41..73b125e55 100644 --- a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesTest.java +++ b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesTest.java @@ -75,6 +75,69 @@ public void testTrim() { } } + @Test + public void testSplit() { + Map tests = new HashMap() {{ + put(new TaintRange(1, 4), "Taints:[untrusted(8,13)]"); + put(new TaintRange(1, 5), "Taints:[untrusted(9,14)]"); + put(new TaintRange(1, 7), "Taints:[untrusted(11,16)]"); + put(new TaintRange(1, 11), "Taints:[untrusted(15,20)]"); + put(new TaintRange(6, 7), "Taints:[untrusted(5,6), untrusted(7,11)]"); + put(new TaintRange(6, 11), "Taints:[untrusted(5,6), untrusted(11,15)]"); + put(new TaintRange(5, 15), "Taints:[untrusted(15,20)]"); + put(new TaintRange(10, 15), "Taints:[untrusted(5,10)]"); + put(new TaintRange(11, 15), "Taints:[untrusted(5,10)]"); + }}; + + for (Map.Entry entry : tests.entrySet()) { + TaintRanges ts = new TaintRanges(new TaintRange(5, 10)); + ts.split(entry.getKey().start, entry.getKey().stop); + Assert.assertEquals(entry.getKey().toString(), entry.getValue(), ts.toString()); + } + } + + @Test + public void testSubRange() { + Map tests = new HashMap() {{ + put(new TaintRange(1, 4), "Taints:[]"); + put(new TaintRange(1, 5), "Taints:[]"); + put(new TaintRange(1, 7), "Taints:[untrusted(5,7)]"); + put(new TaintRange(1, 11), "Taints:[untrusted(5,10)]"); + put(new TaintRange(6, 7), "Taints:[untrusted(6,7)]"); + put(new TaintRange(6, 11), "Taints:[untrusted(6,10)]"); + put(new TaintRange(5, 15), "Taints:[untrusted(5,10)]"); + put(new TaintRange(10, 15), "Taints:[]"); + put(new TaintRange(11, 15), "Taints:[]"); + }}; + + for (Map.Entry entry : tests.entrySet()) { + TaintRanges ts = new TaintRanges(new TaintRange(5, 10)); + ts.subRange(entry.getKey().start, entry.getKey().stop); + Assert.assertEquals(entry.getKey().toString(), entry.getValue(), ts.toString()); + } + } + + @Test + public void testClear() { + Map tests = new HashMap() {{ + put(new TaintRange(1, 4), "Taints:[untrusted(5,10)]"); + put(new TaintRange(1, 5), "Taints:[untrusted(5,10)]"); + put(new TaintRange(1, 7), "Taints:[untrusted(7,10)]"); + put(new TaintRange(1, 11), "Taints:[]"); + put(new TaintRange(6, 7), "Taints:[untrusted(5,6), untrusted(7,10)]"); + put(new TaintRange(6, 11), "Taints:[untrusted(5,6)]"); + put(new TaintRange(5, 15), "Taints:[]"); + put(new TaintRange(10, 15), "Taints:[untrusted(5,10)]"); + put(new TaintRange(11, 15), "Taints:[untrusted(5,10)]"); + }}; + + for (Map.Entry entry : tests.entrySet()) { + TaintRanges ts = new TaintRanges(new TaintRange(5, 10)); + ts.clear(entry.getKey().start, entry.getKey().stop); + Assert.assertEquals(entry.getKey().toString(), entry.getValue(), ts.toString()); + } + } + @Test public void testMerge() { TaintRange tr1; From fe7d459ef3f9d49108c5b0336d117fe212e8306a Mon Sep 17 00:00:00 2001 From: lostsnow Date: Tue, 16 Aug 2022 19:04:40 +0800 Subject: [PATCH 04/19] add TaintRanges.remove --- .../vulscan/taintrange/TaintRanges.java | 35 +++++++++++++++++++ .../vulscan/taintrange/TaintRangesTest.java | 21 +++++++++++ 2 files changed, 56 insertions(+) diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRanges.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRanges.java index d4028335f..de01f9320 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRanges.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRanges.java @@ -144,6 +144,41 @@ public void subRange(int start, int stop) { } } + public void remove(int start, int stop) { + if (start < 0) { + throw new RuntimeException("taint range remove invalid start: " + start); + } + if (stop < start) { + throw new RuntimeException("taint range remove invalid stop: " + stop + " < start:" + start); + } + if (stop != start) { + int length = stop - start; + Iterator it = this.taintRanges.iterator(); + while (it.hasNext()) { + TaintRange next = it.next(); + switch (next.compareRange(start, stop)) { + case LOW_SPAN: + next.stop = start; + break; + case WITHIN: + it.remove(); + break; + case CONTAIN: + next.stop -= length; + break; + case HIGH_SPAN: + next.start = start; + next.stop -= stop - next.start; + break; + case ABOVE: + next.start -= length; + next.stop -= length; + break; + } + } + } + } + public void clear(int start, int stop) { if (start < 0) { throw new RuntimeException("taint range clear invalid start: " + start); diff --git a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesTest.java b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesTest.java index 73b125e55..003b89eb9 100644 --- a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesTest.java +++ b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesTest.java @@ -117,6 +117,27 @@ public void testSubRange() { } } + @Test + public void testRemove() { + Map tests = new HashMap() {{ + put(new TaintRange(1, 4), "Taints:[untrusted(2,7)]"); + put(new TaintRange(1, 5), "Taints:[untrusted(1,6)]"); + put(new TaintRange(1, 7), "Taints:[untrusted(1,4)]"); + put(new TaintRange(1, 11), "Taints:[]"); + put(new TaintRange(6, 7), "Taints:[untrusted(5,9)]"); + put(new TaintRange(6, 11), "Taints:[untrusted(5,6)]"); + put(new TaintRange(5, 15), "Taints:[]"); + put(new TaintRange(10, 15), "Taints:[untrusted(5,10)]"); + put(new TaintRange(11, 15), "Taints:[untrusted(5,10)]"); + }}; + + for (Map.Entry entry : tests.entrySet()) { + TaintRanges ts = new TaintRanges(new TaintRange(5, 10)); + ts.remove(entry.getKey().start, entry.getKey().stop); + Assert.assertEquals(entry.getKey().toString(), entry.getValue(), ts.toString()); + } + } + @Test public void testClear() { Map tests = new HashMap() {{ From 2bac8298358ffcb0bb9b82148eb4fbcc9ccc30ce Mon Sep 17 00:00:00 2001 From: lostsnow Date: Fri, 19 Aug 2022 10:24:37 +0800 Subject: [PATCH 05/19] taint range add remove/concat/trim --- .../vulscan/taintrange/TaintRanges.java | 10 +++ .../taintrange/TaintRangesBuilder.java | 80 ++++++++++++++++++ .../TaintRangeBuilderConcatTest.java | 23 +++++ .../TaintRangeBuilderRemoveTest.java | 83 +++++++++++++++++++ .../taintrange/TaintRangeBuilderTrimTest.java | 48 +++++++++++ 5 files changed, 244 insertions(+) create mode 100644 dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderConcatTest.java create mode 100644 dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderRemoveTest.java create mode 100644 dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderTrimTest.java diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRanges.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRanges.java index de01f9320..1ab8bc165 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRanges.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRanges.java @@ -31,6 +31,12 @@ public void addAll(TaintRanges taintRanges) { } } + public void addAll(Collection taintRanges) { + if (taintRanges != null) { + this.taintRanges.addAll(taintRanges); + } + } + public TaintRanges clone() { TaintRanges taintRanges = new TaintRanges(); int size = this.taintRanges.size(); @@ -40,6 +46,10 @@ public TaintRanges clone() { return taintRanges; } + public boolean isEmpty() { + return this.taintRanges.isEmpty(); + } + public void shift(int i) { for (TaintRange taintRange : this.taintRanges) { if (taintRange.start + i < 0 || taintRange.stop + i < 0) { diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesBuilder.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesBuilder.java index 8b5f8bf91..41b77b2e5 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesBuilder.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesBuilder.java @@ -4,6 +4,19 @@ import java.io.StringWriter; public class TaintRangesBuilder { + public enum Command { + KEEP, + APPEND, + SUBSET, + INSERT, + REMOVE, + REPLACE, + CONCAT, + TRIM, + TRIM_RIGHT, + TRIM_LEFT, + } + public void keep(TaintRanges taintRanges, Object target, int argC, TaintRanges tgtTaintRanges) { if (argC == 0) { int length = this.getLength(target); @@ -97,6 +110,73 @@ public void insert(TaintRanges taintRanges, TaintRanges srcTaintRanges, Object s taintRanges.merge(); } + public void remove(TaintRanges taintRanges, Object source, TaintRanges tgtTaintRanges, int p1, int p2, int argC) { + switch (argC) { + case 0: + tgtTaintRanges.remove(0, this.getLength(source)); + break; + case 1: + tgtTaintRanges.remove(p1, p1 + 1); + taintRanges.addAll(tgtTaintRanges); + break; + case 2: + tgtTaintRanges.remove(p1, p2); + taintRanges.addAll(tgtTaintRanges); + break; + default: + return; + } + taintRanges.merge(); + } + + public void replace(TaintRanges taintRanges, Object target, TaintRanges srcTaintRanges, TaintRanges tgtTaintRanges) { + // @TODO + taintRanges.add(new TaintRange(0, this.getLength(target))); + } + + public void concat(TaintRanges taintRanges, Object target, TaintRanges srcTaintRanges, Object source, TaintRanges tgtTaintRanges, Object[] params) { + if (params != null && params.length == 1 && source.equals(params[0])) { + tgtTaintRanges.shift(this.getLength(target) - this.getLength(source)); + } + taintRanges.addAll(srcTaintRanges); + taintRanges.addAll(tgtTaintRanges); + taintRanges.merge(); + } + + public void trim(Command command, TaintRanges taintRanges, Object source, TaintRanges tgtTaintRanges, int argC) { + if (argC > 0) { + return; + } + if (!tgtTaintRanges.isEmpty()) { + if (!(source instanceof CharSequence)) { + taintRanges.addAll(tgtTaintRanges.getTaintRanges()); + return; + } + int left = 0; + CharSequence charSequence = (CharSequence) source; + int length = charSequence.length(); + if (command.equals(Command.TRIM) || command.equals(Command.TRIM_LEFT)) { + while (left < length && Character.isWhitespace(charSequence.charAt(left))) { + left++; + } + } + if (command.equals(Command.TRIM) || command.equals(Command.TRIM_RIGHT)) { + int right = length; + while (right > 0 && Character.isWhitespace(charSequence.charAt(right - 1))) { + right--; + } + length = right; + } + for (TaintRange taintRange : tgtTaintRanges.getTaintRanges()) { + int max = Math.max(0, taintRange.getStart() - left); + int min = Math.min(length, taintRange.getStop()) - left; + if (min > max) { + taintRanges.add(new TaintRange(taintRange.getName(), max, min)); + } + } + } + } + public int getLength(Object obj) { if (obj == null) { return 0; diff --git a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderConcatTest.java b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderConcatTest.java new file mode 100644 index 000000000..f5e34f70a --- /dev/null +++ b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderConcatTest.java @@ -0,0 +1,23 @@ +package io.dongtai.iast.core.handler.hookpoint.vulscan.taintrange; + +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; + +public class TaintRangeBuilderConcatTest { + @Test + public void testConcat() throws IOException { + TaintRanges ts; + TaintRanges srcTs; + TaintRanges tgtTs; + TaintRangesBuilder tb = new TaintRangesBuilder(); + + ts = new TaintRanges(); + srcTs = new TaintRanges(new TaintRange(1, 3)); + tgtTs = new TaintRanges(new TaintRange(0, 2)); + // "fOO".concat("BAr") // fOOBAr + tb.concat(ts, "fOOBAr", srcTs, "BAr", tgtTs, new String[]{"BAr"}); + Assert.assertEquals("Taints:[untrusted(1,5)]", ts.toString()); + } +} diff --git a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderRemoveTest.java b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderRemoveTest.java new file mode 100644 index 000000000..98166ccd8 --- /dev/null +++ b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderRemoveTest.java @@ -0,0 +1,83 @@ +package io.dongtai.iast.core.handler.hookpoint.vulscan.taintrange; + +import org.junit.Assert; +import org.junit.Test; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +public class TaintRangeBuilderRemoveTest { + @Test + public void testRemoveReset() throws IOException { + TaintRanges ts; + TaintRanges tgtTs; + TaintRangesBuilder tb = new TaintRangesBuilder(); + ByteArrayOutputStream baos; + + ts = new TaintRanges(); + tgtTs = new TaintRanges(new TaintRange(0, 6)); + // new ByteArrayOutputStream(6).write("FOOBAR".getBytes()).reset() + baos = new ByteArrayOutputStream(6); + baos.write("FOOBAR".getBytes()); + tb.remove(ts, baos, tgtTs, 0, 0, 0); + Assert.assertEquals("Taints:[]", ts.toString()); + + ts = new TaintRanges(); + tgtTs = new TaintRanges(new TaintRange(3, 6)); + // new ByteArrayOutputStream(6).write("fooBAR".getBytes()).reset() + baos = new ByteArrayOutputStream(6); + baos.write("fooBAR".getBytes()); + tb.remove(ts, baos, tgtTs, 0, 0, 0); + Assert.assertEquals("Taints:[]", ts.toString()); + } + + @Test + public void testRemoveCharAt() { + TaintRanges ts; + TaintRanges tgtTs; + TaintRangesBuilder tb = new TaintRangesBuilder(); + + ts = new TaintRanges(); + tgtTs = new TaintRanges(new TaintRange(0, 7)); + // new StringBuilder("FOOZBAR").deleteCharAt(3) // FOOBAR + tb.remove(ts, new StringBuilder("FOOBAR"), tgtTs, 3, 0, 1); + Assert.assertEquals("Taints:[untrusted(0,6)]", ts.toString()); + + ts = new TaintRanges(); + tgtTs = new TaintRanges(new TaintRange(1, 6)); + // new StringBuilder("fOOZBAr").deleteCharAt(3) // fOOBAr + tb.remove(ts, new StringBuilder("fOOBAr"), tgtTs, 3, 0, 1); + Assert.assertEquals("Taints:[untrusted(1,5)]", ts.toString()); + + ts = new TaintRanges(); + tgtTs = new TaintRanges(new TaintRange(0, 3), new TaintRange(4, 7)); + // new StringBuilder("FOOzBAR").deleteCharAt(3) // FOOBAR + tb.remove(ts, new StringBuilder("FOOBAR"), tgtTs, 3, 0, 1); + Assert.assertEquals("Taints:[untrusted(0,6)]", ts.toString()); + } + + @Test + public void testRemoveStartStop() { + TaintRanges ts; + TaintRanges tgtTs; + TaintRangesBuilder tb = new TaintRangesBuilder(); + + ts = new TaintRanges(); + tgtTs = new TaintRanges(new TaintRange(0, 9)); + // new StringBuilder("FOOZZZBAR").delete(3, 6) // FOOBAR + tb.remove(ts, new StringBuilder("FOOBAR"), tgtTs, 3, 6, 2); + Assert.assertEquals("Taints:[untrusted(0,6)]", ts.toString()); + + ts = new TaintRanges(); + tgtTs = new TaintRanges(new TaintRange(1, 8)); + // new StringBuilder("fOOZZZBAr").delete(3, 6) // fOOBAr + tb.remove(ts, new StringBuilder("fOOBAr"), tgtTs, 3, 6, 2); + Assert.assertEquals("Taints:[untrusted(1,5)]", ts.toString()); + + ts = new TaintRanges(); + tgtTs = new TaintRanges(new TaintRange(0, 3), new TaintRange(4, 5), new TaintRange(6, 9)); + // new StringBuilder("FOOzZzBAR").delete(3, 6) // FOOBAR + tb.remove(ts, new StringBuilder("FOOBAR"), tgtTs, 3, 6, 2); + Assert.assertEquals("Taints:[untrusted(0,6)]", ts.toString()); + } +} diff --git a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderTrimTest.java b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderTrimTest.java new file mode 100644 index 000000000..35a462404 --- /dev/null +++ b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderTrimTest.java @@ -0,0 +1,48 @@ +package io.dongtai.iast.core.handler.hookpoint.vulscan.taintrange; + +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; + +public class TaintRangeBuilderTrimTest { + @Test + public void testTrim() { + TaintRanges ts; + + TaintRanges tgtTs; + TaintRangesBuilder tb = new TaintRangesBuilder(); + + ts = new TaintRanges(); + tgtTs = new TaintRanges(new TaintRange(3, 7)); + // " fOOBAr ".trim() // fOOBAr + tb.trim(TaintRangesBuilder.Command.TRIM, ts, " fOOBAr ", tgtTs, 0); + Assert.assertEquals("Taints:[untrusted(1,5)]", ts.toString()); + } + + @Test + public void testTrimLeft() { + TaintRanges ts; + TaintRanges tgtTs; + TaintRangesBuilder tb = new TaintRangesBuilder(); + + ts = new TaintRanges(); + tgtTs = new TaintRanges(new TaintRange(3, 7)); + // " fOOBAr".trim() // fOOBAr + tb.trim(TaintRangesBuilder.Command.TRIM_LEFT, ts, " fOOBAr", tgtTs, 0); + Assert.assertEquals("Taints:[untrusted(1,5)]", ts.toString()); + } + + @Test + public void testTrimRight() throws IOException { + TaintRanges ts; + TaintRanges tgtTs; + TaintRangesBuilder tb = new TaintRangesBuilder(); + + ts = new TaintRanges(); + tgtTs = new TaintRanges(new TaintRange(1, 5)); + // "fOOBAr ".trim() // fOOBAr + tb.trim(TaintRangesBuilder.Command.TRIM_RIGHT, ts, "fOOBAr ", tgtTs, 0); + Assert.assertEquals("Taints:[untrusted(1,5)]", ts.toString()); + } +} From 5ff946e844c634fc58d7afa8553ec2111dca556c Mon Sep 17 00:00:00 2001 From: lostsnow Date: Mon, 22 Aug 2022 18:27:15 +0800 Subject: [PATCH 06/19] add target range to source methods --- .../controller/impl/PropagatorImpl.java | 16 +-- .../hookpoint/controller/impl/SourceImpl.java | 106 +++++++++++++++++- .../framework/dubbo/DubboHandler.java | 4 +- .../hookpoint/graphy/GraphBuilder.java | 16 +-- .../handler/hookpoint/graphy/GraphNode.java | 15 ++- .../handler/hookpoint/models/MethodEvent.java | 46 +++++++- .../hookpoint/service/kafka/KafkaHandler.java | 2 +- .../dynamic/DynamicPropagatorScanner.java | 4 +- .../hookpoint/vulscan/dynamic/TrackUtils.java | 32 +++--- .../vulscan/taintrange/TaintRange.java | 10 ++ .../vulscan/taintrange/TaintRanges.java | 10 ++ .../taintrange/TaintRangesBuilder.java | 22 ++++ .../iast/core/utils/TaintPoolUtils.java | 15 +++ .../core/utils/threadlocal/IastTaintPool.java | 82 +++++++------- 14 files changed, 289 insertions(+), 91 deletions(-) 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 e0230eec1..1525897af 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 @@ -54,7 +54,7 @@ private static void auxiliaryPropagator(IastPropagatorModel propagator, AtomicIn return; } - event.inValue = event.object; + event.setInValue(event.object); setTarget(propagator, event); addPropagator(event, invokeIdSequencer); } else if (sourceString.startsWith(PARAMS_PARAM)) { @@ -74,7 +74,7 @@ private static void auxiliaryPropagator(IastPropagatorModel propagator, AtomicIn inValues.add(tempObj); } if (!inValues.isEmpty()) { - event.inValue = inValues.toArray(); + event.setInValue(inValues.toArray()); setTarget(propagator, event); addPropagator(event, invokeIdSequencer); } @@ -95,7 +95,7 @@ private static void auxiliaryPropagator(IastPropagatorModel propagator, AtomicIn if (event.returnValue == null) { break; } - inValues.add(event.returnValue); + event.setInValue(event.returnValue); } else if (source.startsWith(PARAMS_PARAM)) { int[] positions = (int[]) propagator.getSourcePosition(); for (int pos : positions) { @@ -116,7 +116,7 @@ private static void auxiliaryPropagator(IastPropagatorModel propagator, AtomicIn } } if (condition > 0 && (!andCondition || conditionSources.length == condition)) { - event.inValue = inValues.toArray(); + event.setInValue(inValues.toArray()); setTarget(propagator, event); addPropagator(event, invokeIdSequencer); } @@ -127,21 +127,21 @@ private static void auxiliaryPropagator(IastPropagatorModel propagator, AtomicIn private static void setTarget(IastPropagatorModel propagator, MethodEvent event) { String target = propagator.getTarget(); if (PARAMS_OBJECT.equals(target)) { - event.outValue = event.object; + event.setOutValue(event.object); } else if (PARAMS_RETURN.equals(target)) { - event.outValue = event.returnValue; + event.setOutValue(event.returnValue); } else if (target.startsWith(PARAMS_PARAM)) { ArrayList outValues = new ArrayList(); Object tempPositions = propagator.getTargetPosition(); int[] positions = (int[]) tempPositions; if (positions.length == 1) { - event.outValue = event.argumentArray[positions[0]]; + event.setOutValue(event.argumentArray[positions[0]]); } else { for (int pos : positions) { outValues.add(event.argumentArray[pos]); } if (!outValues.isEmpty()) { - event.outValue = outValues.toArray(); + event.setOutValue(outValues.toArray()); } } } diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/controller/impl/SourceImpl.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/controller/impl/SourceImpl.java index a1c3d56ae..d2d7524cc 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/controller/impl/SourceImpl.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/controller/impl/SourceImpl.java @@ -2,10 +2,12 @@ import io.dongtai.iast.core.EngineManager; import io.dongtai.iast.core.handler.hookpoint.models.MethodEvent; +import io.dongtai.iast.core.handler.hookpoint.vulscan.taintrange.*; import io.dongtai.iast.core.utils.StackUtils; import io.dongtai.iast.core.utils.TaintPoolUtils; import io.dongtai.log.DongTaiLog; +import java.lang.reflect.Array; import java.lang.reflect.Method; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; @@ -37,25 +39,117 @@ public static void solveSource(MethodEvent event, AtomicInteger invokeIdSequence int invokeId = invokeIdSequencer.getAndIncrement(); event.setInvokeId(invokeId); - event.inValue = event.argumentArray; - event.outValue = event.returnValue; + event.setInValue(event.argumentArray); + event.setOutValue(event.returnValue); - handlerCustomModel(event); EngineManager.TRACK_MAP.addTrackMethod(invokeId, event); - EngineManager.TAINT_POOL.addTaintToPool(event.returnValue, event, true); + trackTarget(event); } + private static void trackTarget(MethodEvent event) { + TaintRangesBuilder tb = new TaintRangesBuilder(); + int length = tb.getLength(event.returnValue); + if (length == 0) { + return; + } + + trackObject(tb, event, event.returnValue, 0); + // @TODO: hook json serializer for custom model + handlerCustomModel(tb, event); + } + + private static void trackObject(TaintRangesBuilder tb, MethodEvent event, Object obj, int depth) { + if (depth >= 10 || !TaintPoolUtils.isNotEmpty(obj) || !TaintPoolUtils.isAllowTaintType(obj)) { + return; + } + + int hash = System.identityHashCode(obj); + if (EngineManager.TAINT_HASH_CODES.get().contains(hash)) { + return; + } + + Class cls = obj.getClass(); + if (cls.isArray() && !cls.getComponentType().isPrimitive()) { + trackArray(tb, event, obj, depth); + } else if (obj instanceof Iterator) { + trackIterator(tb, event, (Iterator) obj, depth); + } else if (obj instanceof Map) { + trackMap(tb, event, (Map) obj, depth); + } else if (obj instanceof Map.Entry) { + trackMapEntry(tb, event, (Map.Entry) obj, depth); + } else if (obj instanceof Collection) { + if (obj instanceof List) { + trackList(tb, event, (List) obj, depth); + } else { + trackIterator(tb, event, ((Collection) obj).iterator(), depth); + } + } else if ("java.util.Optional".equals(obj.getClass().getName())) { + trackOptional(tb, event, obj, depth); + } else { + int len = tb.getLength(obj); + if (len == 0) { + return; + } + + TaintRanges tr = new TaintRanges(new TaintRange(0, len)); + event.targetRanges.add(new MethodEvent.MethodEventTargetRange(hash, tb.obj2String(obj), tr)); + EngineManager.TAINT_HASH_CODES.get().add(hash); + event.addTargetHash(hash); + event.addTargetHashForRpc(obj.hashCode()); + EngineManager.TAINT_POOL.get().add(obj); + } + } + + private static void trackArray(TaintRangesBuilder tb, MethodEvent event, Object arr, int depth) { + int length = Array.getLength(arr); + for (int i = 0; i < length; i++) { + trackObject(tb, event, Array.get(arr, i), depth); + } + } + + private static void trackIterator(TaintRangesBuilder tb, MethodEvent event, Iterator it, int depth) { + while (it.hasNext()) { + trackObject(tb, event, it.next(), depth + 1); + } + } + + private static void trackMap(TaintRangesBuilder tb, MethodEvent event, Map map, int depth) { + for (Object key : map.keySet()) { + trackObject(tb, event, key, depth); + trackObject(tb, event, map.get(key), depth); + } + } + + private static void trackMapEntry(TaintRangesBuilder tb, MethodEvent event, Map.Entry entry, int depth) { + trackObject(tb, event, entry.getKey(), depth + 1); + trackObject(tb, event, entry.getValue(), depth + 1); + } + + private static void trackList(TaintRangesBuilder tb, MethodEvent event, List list, int depth) { + for (Object obj : list) { + trackObject(tb, event, obj, depth); + } + } + + private static void trackOptional(TaintRangesBuilder tb, MethodEvent event, Object obj, int depth) { + try { + Object v = ((Optional) obj).orElse(null); + trackObject(tb, event, v, depth); + } catch (Exception e) { + DongTaiLog.warn("track optional object failed: " + e.getMessage()); + } + } /** * todo: 处理过程和结果需要细化 * * @param event MethodEvent */ - public static void handlerCustomModel(MethodEvent event) { + public static void handlerCustomModel(TaintRangesBuilder tb, MethodEvent event) { if (!event.getMethodName().equals("getSession")) { Set modelValues = parseCustomModel(event.returnValue); for (Object modelValue : modelValues) { - EngineManager.TAINT_POOL.addTaintToPool(modelValue, event, true); + trackObject(tb, event, modelValue, 0); } } } diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/framework/dubbo/DubboHandler.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/framework/dubbo/DubboHandler.java index fb0943e3b..fd091da43 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/framework/dubbo/DubboHandler.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/framework/dubbo/DubboHandler.java @@ -102,7 +102,7 @@ public static void solveDubbo(MethodEvent event, AtomicInteger invokeIdSequencer int invokeId = invokeIdSequencer.getAndIncrement(); event.setInvokeId(invokeId); event.inValue = ""; - event.outValue = verifiedArguments; + event.setOutValue(verifiedArguments); EngineManager.TRACK_MAP.addTrackMethod(invokeId, event); EngineManager.TAINT_POOL.addTaintToPool(verifiedArguments, event, true); @@ -223,7 +223,7 @@ public static void solveClientExit(Object invocation, Object rpcResult) { EngineManager.TAINT_HASH_CODES.get().add(identityHashCode); } } - event.outValue = resModelSet; + event.setOutValue(resModelSet); } } diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/graphy/GraphBuilder.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/graphy/GraphBuilder.java index ed245afb7..de1a5773a 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/graphy/GraphBuilder.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/graphy/GraphBuilder.java @@ -1,7 +1,6 @@ package io.dongtai.iast.core.handler.hookpoint.graphy; import io.dongtai.iast.core.EngineManager; -import io.dongtai.iast.core.utils.PropertyUtils; import io.dongtai.iast.core.bytecode.enhance.IastClassDiagram; import io.dongtai.iast.core.handler.hookpoint.controller.impl.HttpImpl; import io.dongtai.iast.core.handler.hookpoint.models.MethodEvent; @@ -9,14 +8,14 @@ import io.dongtai.iast.core.handler.hookpoint.vulscan.normal.AbstractNormalVulScan; import io.dongtai.iast.core.service.ThreadPools; import io.dongtai.iast.core.utils.Constants; +import io.dongtai.iast.core.utils.PropertyUtils; import io.dongtai.iast.core.utils.base64.Base64Encoder; - -import java.util.*; - import io.dongtai.log.DongTaiLog; import org.json.JSONArray; import org.json.JSONObject; +import java.util.*; + /** * @author dongzhiyong@huoxian.cn */ @@ -63,16 +62,17 @@ public static List build() { "", event.getSourceHashes(), event.getTargetHashes(), - properties.isLocal() ? event.obj2String(event.inValue) : "", - properties.isLocal() && event.objIsReference(event.inValue), - properties.isLocal() ? event.obj2String(event.outValue) : "", + event.inValueString, properties.isLocal() && event.objIsReference(event.inValue), + event.outValueString, + properties.isLocal() && event.objIsReference(event.outValue), event.getSourceHashForRpc(), event.getTargetHashForRpc(), event.getTraceId(), event.getServiceName(), event.getPlugin(), - event.getProjectPropagatorClose() + event.getProjectPropagatorClose(), + event.targetRanges ) ); }catch (Exception e){ diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/graphy/GraphNode.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/graphy/GraphNode.java index 2f49ae0d5..4b5ebf362 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/graphy/GraphNode.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/graphy/GraphNode.java @@ -1,9 +1,10 @@ package io.dongtai.iast.core.handler.hookpoint.graphy; +import io.dongtai.iast.core.handler.hookpoint.models.MethodEvent; import org.json.JSONArray; import org.json.JSONObject; -import java.util.Set; +import java.util.*; /** * 图节点,用于服务器端污点方法图的构造 @@ -115,6 +116,8 @@ public void setInterfaceNames(Set interfaceNames) { private final String plugin; private final Boolean projectPropagatorClose; + private List targetRanges = new ArrayList(); + public GraphNode(boolean isSource, int invokeId, String callerClass, @@ -138,7 +141,8 @@ public GraphNode(boolean isSource, String traceId, String serviceName, String plugin, - Boolean projectPropagatorClose + Boolean projectPropagatorClose, + List targetRanges ) { this.isSource = isSource; this.invokeId = invokeId; @@ -164,6 +168,7 @@ public GraphNode(boolean isSource, this.serviceName = serviceName; this.plugin = plugin; this.projectPropagatorClose = projectPropagatorClose; + this.targetRanges = targetRanges; } public JSONObject toJson() { @@ -222,6 +227,12 @@ public JSONObject toJson() { targetHashForRpcArray.put(hash); } + JSONArray tr = new JSONArray(); + value.put("targetRange", tr); + for (MethodEvent.MethodEventTargetRange range : targetRanges) { + tr.put(range.toJson()); + } + return value; } } diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/models/MethodEvent.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/models/MethodEvent.java index 290390421..b790dac71 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/models/MethodEvent.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/models/MethodEvent.java @@ -1,11 +1,11 @@ package io.dongtai.iast.core.handler.hookpoint.models; +import io.dongtai.iast.core.handler.hookpoint.vulscan.taintrange.TaintRanges; +import io.dongtai.iast.core.utils.PropertyUtils; import io.dongtai.log.DongTaiLog; +import org.json.JSONObject; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; /** * 方法事件 @@ -83,6 +83,8 @@ public String getMethodDesc() { */ public Object inValue; + public String inValueString = ""; + public Set getSourceHashes() { return sourceHashes; } @@ -129,6 +131,8 @@ public void addTargetHashForRpc(int hash) { */ public Object outValue; + public String outValueString = ""; + /** * 方法的签名 */ @@ -200,6 +204,28 @@ public void setProjectPropagatorClose(Boolean projectPropagatorClose) { public Boolean projectPropagatorClose = false; + public List targetRanges = new ArrayList(); + + public static class MethodEventTargetRange { + private final Integer hash; + private final String value; + private final TaintRanges ranges; + + public MethodEventTargetRange(Integer hash, String value, TaintRanges ranges) { + this.hash = hash; + this.value = value; + this.ranges = ranges; + } + + public JSONObject toJson() { + JSONObject json = new JSONObject(); + json.put("hash", this.hash); + json.put("value", this.value); + json.put("ranges", this.ranges.toJson()); + return json; + } + } + /** * 构造调用事件 * @@ -390,4 +416,16 @@ public String getPlugin() { public void setPlugin(String plugin) { this.plugin = plugin; } + + public void setInValue(Object inValue) { + PropertyUtils properties = PropertyUtils.getInstance(); + this.inValue = inValue; + this.inValueString = properties.isLocal() ? obj2String(inValue) : ""; + } + + public void setOutValue(Object outValue) { + PropertyUtils properties = PropertyUtils.getInstance(); + this.outValue = outValue; + this.outValueString = properties.isLocal() ? obj2String(outValue) : ""; + } } diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/service/kafka/KafkaHandler.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/service/kafka/KafkaHandler.java index f98089582..faf6c409e 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/service/kafka/KafkaHandler.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/service/kafka/KafkaHandler.java @@ -130,7 +130,7 @@ public static void afterPoll(Object record) { Set resModelSet = new HashSet(); resModelSet.add(rd); - event.outValue = resModelSet; + event.setOutValue(resModelSet); EngineManager.TRACK_MAP.addTrackMethod(invokeId, event); EngineManager.TAINT_POOL.addTaintToPool(rd, event, true); diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/DynamicPropagatorScanner.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/DynamicPropagatorScanner.java index fe42260ea..8e1a09116 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/DynamicPropagatorScanner.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/DynamicPropagatorScanner.java @@ -110,12 +110,12 @@ private boolean sinkSourceHitTaintPool(MethodEvent event, IastSinkModel sink) { } } if (hitTaintPool) { - event.inValue = sourceValue; + event.setInValue(sourceValue); } } else { hitTaintPool = TaintPoolUtils.poolContains(event.object, event); if (hitTaintPool) { - event.inValue = event.object; + event.setInValue(event.object); } } } diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/TrackUtils.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/TrackUtils.java index c0d35ec4d..d5e94fd73 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/TrackUtils.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/TrackUtils.java @@ -3,9 +3,7 @@ import io.dongtai.iast.core.handler.hookpoint.models.MethodEvent; import io.dongtai.iast.core.utils.StringUtils; -import java.util.Collection; -import java.util.List; -import java.util.Map; +import java.util.*; /** * @author dongzhiyong@huoxian.cn @@ -134,10 +132,10 @@ public static boolean smartEventMatchAndSetTaint(Object taintValue, MethodEvent if (!matchArg) { // 污点与方法返回值相同,本身相同,参数不同 - event.inValue = event.object; + event.setInValue(event.object); matchStatus = true; } else { - event.inValue = argTaint; + event.setInValue(argTaint); matchStatus = true; } } else { @@ -166,12 +164,12 @@ public static boolean smartEventMatchAndSetTaint(Object taintValue, MethodEvent if (matchArg) { // 污点与方法返回值相同、本身不同、参数相同,传播值本身,参数 - event.inValue = argTaint; + event.setInValue(argTaint); matchStatus = true; } else { // 如果方法没有参数,设置污点为对象; if (event.argumentArray.length == 0) { - event.inValue = event.object; + event.setInValue(event.object); } /*else if (event.isStatic) { // 如果方法有参数,设置污点为参数 event.inValue = event.argumentArray; @@ -180,7 +178,7 @@ public static boolean smartEventMatchAndSetTaint(Object taintValue, MethodEvent } } if (matchStatus) { - event.outValue = event.returnValue; + event.setOutValue(event.returnValue); } } else { // 污点与方法返回值不同 @@ -202,14 +200,14 @@ public static boolean smartEventMatchAndSetTaint(Object taintValue, MethodEvent // 污点与方法返回值不同、本身相同、参数不同 if (!matchArg) { - event.inValue = event.object; + event.setInValue(event.object); matchStatus = true; } else { - event.inValue = argTaint; + event.setInValue(argTaint); matchStatus = true; } if (matchStatus) { - event.outValue = event.object; + event.setOutValue(event.object); } } else { // 污点与方法返回值、方法本身不相同 @@ -228,8 +226,8 @@ public static boolean smartEventMatchAndSetTaint(Object taintValue, MethodEvent } if (matchArg) { - event.inValue = argTaint; - event.outValue = argTaint; + event.setInValue(argTaint); + event.setOutValue(argTaint); matchStatus = true; } } @@ -253,9 +251,9 @@ public static boolean smartEventMatchAndSetTaint(Object taintValue, MethodEvent } if (!matchArg) { - event.inValue = event.object; + event.setInValue(event.object); } else { - event.inValue = argTaint; + event.setInValue(argTaint); } } else { // 污点与方法本身不相同 @@ -274,10 +272,10 @@ public static boolean smartEventMatchAndSetTaint(Object taintValue, MethodEvent } // 污点与方法返回值相同、本身不同、参数相同 if (matchArg) { - event.inValue = argTaint; + event.setInValue(argTaint); } else { // 如果方法未执行完,且污点与参数、本身均不同,则加入当前污点为方法污点 - event.inValue = taintValue; + event.setInValue(taintValue); } } matchStatus = true; diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRange.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRange.java index f387ea5d7..04fef8ef8 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRange.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRange.java @@ -1,5 +1,7 @@ package io.dongtai.iast.core.handler.hookpoint.vulscan.taintrange; +import org.json.JSONObject; + public class TaintRange { public static final String UNTRUSTED = "untrusted"; @@ -130,4 +132,12 @@ public RangeRelation compareRange(int low, int high) { public String toString() { return this.name + "(" + this.start + "," + this.stop + ")"; } + + public JSONObject toJson() { + JSONObject json = new JSONObject(); + json.put("name", this.name); + json.put("start", this.start); + json.put("stop", this.stop); + return json; + } } diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRanges.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRanges.java index 1ab8bc165..66eb58b6e 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRanges.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRanges.java @@ -1,5 +1,7 @@ package io.dongtai.iast.core.handler.hookpoint.vulscan.taintrange; +import org.json.JSONArray; + import java.util.*; public class TaintRanges { @@ -250,4 +252,12 @@ public void merge() { public String toString() { return "Taints:" + this.taintRanges; } + + public JSONArray toJson() { + JSONArray json = new JSONArray(); + for (TaintRange tr : this.taintRanges) { + json.put(tr.toJson()); + } + return json; + } } diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesBuilder.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesBuilder.java index 41b77b2e5..73b3055db 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesBuilder.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesBuilder.java @@ -177,6 +177,28 @@ public void trim(Command command, TaintRanges taintRanges, Object source, TaintR } } + public String obj2String(Object obj) { + if (obj == null) { + return ""; + } + + if (obj instanceof CharSequence) { + return ((CharSequence) obj).toString(); + } else if (obj instanceof StringWriter) { + return ((StringWriter) obj).getBuffer().toString(); + } else if (obj instanceof ByteArrayOutputStream) { + return ((ByteArrayOutputStream) obj).toString(); + } else if (obj instanceof Character) { + return ((Character) obj).toString(); + } else if (obj instanceof byte[]) { + return new String((byte[]) obj); + } else if (obj instanceof char[]) { + return new String((char[]) obj); + } else { + return (obj.getClass().getName() + "@" + Integer.toHexString(obj.hashCode())); + } + } + public int getLength(Object obj) { if (obj == null) { return 0; diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/utils/TaintPoolUtils.java b/dongtai-core/src/main/java/io/dongtai/iast/core/utils/TaintPoolUtils.java index 024c7fc59..90ff24376 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/utils/TaintPoolUtils.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/utils/TaintPoolUtils.java @@ -142,15 +142,30 @@ public static boolean isNotEmpty(Object obj) { public static boolean isAllowTaintType(Class objType) { return objType != Boolean.class && + objType != Boolean[].class && + objType != Short.class && + objType != Short[].class && objType != Integer.class && + objType != Integer[].class && objType != Long.class && + objType != Long[].class && objType != Double.class && + objType != Double[].class && objType != Float.class && + objType != Float[].class && objType != BigDecimal.class && + objType != BigDecimal[].class && objType != boolean.class && + objType != boolean[].class && + objType != short.class && + objType != short[].class && objType != int.class && + objType != int[].class && objType != long.class && + objType != long[].class && objType != double.class && + objType != double[].class && + objType != float[].class && objType != float.class; } diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/utils/threadlocal/IastTaintPool.java b/dongtai-core/src/main/java/io/dongtai/iast/core/utils/threadlocal/IastTaintPool.java index 4f8242fc4..21ec05a98 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/utils/threadlocal/IastTaintPool.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/utils/threadlocal/IastTaintPool.java @@ -35,51 +35,51 @@ public void addTaintToPool(Object obj, MethodEvent event, boolean isSource) { this.get().add(obj); event.addTargetHash(obj.hashCode()); - String[] tempObjs = (String[]) obj; - if (PROPERTIES.isNormalMode()) { - for (String tempObj : tempObjs) { - this.get().add(tempObj); - subHashCode = System.identityHashCode(tempObj); - EngineManager.TAINT_HASH_CODES.get().add(subHashCode); - event.addTargetHash(subHashCode); - event.addTargetHashForRpc(tempObj.hashCode()); - } - } else { - for (String tempObj : tempObjs) { - this.get().add(tempObj); - event.addTargetHash(tempObj.hashCode()); + String[] tempObjs = (String[]) obj; + if (PROPERTIES.isNormalMode()) { + for (String tempObj : tempObjs) { + this.get().add(tempObj); + subHashCode = System.identityHashCode(tempObj); + EngineManager.TAINT_HASH_CODES.get().add(subHashCode); + event.addTargetHash(subHashCode); + event.addTargetHashForRpc(tempObj.hashCode()); + } + } else { + for (String tempObj : tempObjs) { + this.get().add(tempObj); + event.addTargetHash(tempObj.hashCode()); + } } - } - } else if (obj instanceof Map) { - this.get().add(obj); - event.addTargetHash(obj.hashCode()); - if (isSource) { - Map tempMap = (Map) obj; - Set> entries = tempMap.entrySet(); - for (Map.Entry entry : entries) { - Object key = entry.getKey(); - Object value = entry.getValue(); - addTaintToPool(key, event, true); - addTaintToPool(value, event, true); + } else if (obj instanceof Map) { + this.get().add(obj); + event.addTargetHash(obj.hashCode()); + if (isSource) { + Map tempMap = (Map) obj; + Set> entries = tempMap.entrySet(); + for (Map.Entry entry : entries) { + Object key = entry.getKey(); + Object value = entry.getValue(); + addTaintToPool(key, event, true); + addTaintToPool(value, event, true); + } } - } - } else if (obj.getClass().isArray() && !obj.getClass().getComponentType().isPrimitive()) { - Object[] tempObjs = (Object[]) obj; - if (tempObjs.length != 0) { - for (Object tempObj : tempObjs) { - addTaintToPool(tempObj, event, isSource); + } else if (obj.getClass().isArray() && !obj.getClass().getComponentType().isPrimitive()) { + Object[] tempObjs = (Object[]) obj; + if (tempObjs.length != 0) { + for (Object tempObj : tempObjs) { + addTaintToPool(tempObj, event, isSource); + } } - } - } else { - this.get().add(obj); - if (obj instanceof String && PROPERTIES.isNormalMode()) { - subHashCode = System.identityHashCode(obj); - EngineManager.TAINT_HASH_CODES.get().add(subHashCode); } else { - subHashCode = obj.hashCode(); - } - event.addTargetHash(subHashCode); - event.addTargetHashForRpc(obj.hashCode()); + this.get().add(obj); + if (obj instanceof String && PROPERTIES.isNormalMode()) { + subHashCode = System.identityHashCode(obj); + EngineManager.TAINT_HASH_CODES.get().add(subHashCode); + } else { + subHashCode = obj.hashCode(); + } + event.addTargetHash(subHashCode); + event.addTargetHashForRpc(obj.hashCode()); } }catch (Exception e){ From fbda5908dc86141649e1d1dcf9835bf536412ee1 Mon Sep 17 00:00:00 2001 From: lostsnow Date: Tue, 23 Aug 2022 16:40:09 +0800 Subject: [PATCH 07/19] propagator taint ranges --- .../io/dongtai/iast/core/EngineManager.java | 11 +- .../controller/impl/PropagatorImpl.java | 65 +++++++++++ .../hookpoint/controller/impl/SourceImpl.java | 1 + .../vulscan/taintrange/TaintCommand.java | 22 ++++ .../taintrange/TaintCommandRunner.java | 103 ++++++++++++++++++ .../utils/threadlocal/TaintRangesPool.java | 21 ++++ 6 files changed, 217 insertions(+), 6 deletions(-) create mode 100644 dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommand.java create mode 100644 dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommandRunner.java create mode 100644 dongtai-core/src/main/java/io/dongtai/iast/core/utils/threadlocal/TaintRangesPool.java diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/EngineManager.java b/dongtai-core/src/main/java/io/dongtai/iast/core/EngineManager.java index 34f218672..ab83be715 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/EngineManager.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/EngineManager.java @@ -1,21 +1,18 @@ package io.dongtai.iast.core; import io.dongtai.iast.core.bytecode.enhance.plugin.fallback.FallbackManager; -import io.dongtai.iast.core.bytecode.enhance.plugin.fallback.report.HookPointRateLimitReport; import io.dongtai.iast.core.bytecode.enhance.plugin.fallback.FallbackSwitch; import io.dongtai.iast.core.handler.context.ContextManager; import io.dongtai.iast.core.handler.hookpoint.IastServer; import io.dongtai.iast.core.handler.hookpoint.models.MethodEvent; import io.dongtai.iast.core.service.ServerAddressReport; -import io.dongtai.iast.core.utils.config.RemoteConfigUtils; -import io.dongtai.iast.core.utils.threadlocal.*; import io.dongtai.iast.core.service.ServiceFactory; import io.dongtai.iast.core.utils.PropertyUtils; +import io.dongtai.iast.core.utils.config.RemoteConfigUtils; +import io.dongtai.iast.core.utils.threadlocal.*; import io.dongtai.log.DongTaiLog; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; +import java.util.*; import java.util.concurrent.atomic.AtomicInteger; /** @@ -35,6 +32,7 @@ public class EngineManager { public static final IastTrackMap TRACK_MAP = new IastTrackMap(); public static final IastTaintPool TAINT_POOL = new IastTaintPool(); public static final IastTaintHashCodes TAINT_HASH_CODES = new IastTaintHashCodes(); + public static final TaintRangesPool TAINT_RANGES_POOL = new TaintRangesPool(); public static final IastScopeTracker SCOPE_TRACKER = new IastScopeTracker(); private static final IastServerPort LOGIN_LOGIC_WEIGHT = new IastServerPort(); /** @@ -138,6 +136,7 @@ public static void cleanThreadState() { EngineManager.TRACK_MAP.remove(); EngineManager.TAINT_POOL.remove(); EngineManager.TAINT_HASH_CODES.remove(); + EngineManager.TAINT_RANGES_POOL.remove(); EngineManager.SCOPE_TRACKER.remove(); FallbackSwitch.clearHeavyHookFallback(); EngineManager.getFallbackManager().getHookRateLimiter().remove(); 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 1525897af..abe223332 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 @@ -3,6 +3,7 @@ import io.dongtai.iast.core.EngineManager; import io.dongtai.iast.core.handler.hookpoint.models.*; import io.dongtai.iast.core.handler.hookpoint.vulscan.dynamic.TrackUtils; +import io.dongtai.iast.core.handler.hookpoint.vulscan.taintrange.*; import io.dongtai.iast.core.utils.StackUtils; import io.dongtai.iast.core.utils.TaintPoolUtils; @@ -128,17 +129,21 @@ private static void setTarget(IastPropagatorModel propagator, MethodEvent event) String target = propagator.getTarget(); if (PARAMS_OBJECT.equals(target)) { event.setOutValue(event.object); + trackTaintRange(propagator, event); } else if (PARAMS_RETURN.equals(target)) { event.setOutValue(event.returnValue); + trackTaintRange(propagator, event); } else if (target.startsWith(PARAMS_PARAM)) { ArrayList outValues = new ArrayList(); Object tempPositions = propagator.getTargetPosition(); int[] positions = (int[]) tempPositions; if (positions.length == 1) { event.setOutValue(event.argumentArray[positions[0]]); + trackTaintRange(propagator, event); } else { for (int pos : positions) { outValues.add(event.argumentArray[pos]); + trackTaintRange(propagator, event); } if (!outValues.isEmpty()) { event.setOutValue(outValues.toArray()); @@ -150,6 +155,66 @@ private static void setTarget(IastPropagatorModel propagator, MethodEvent event) } } + private static TaintRanges getTaintRanges(Object obj) { + int hash = System.identityHashCode(obj); + TaintRanges tr = EngineManager.TAINT_RANGES_POOL.get(hash); + if (tr == null) { + tr = new TaintRanges(); + } else { + tr = tr.clone(); + } + return tr; + } + + private static void trackTaintRange(IastPropagatorModel propagator, MethodEvent event) { + TaintCommandRunner r = TaintCommand.getCommand(event.signature); + if (r == null) { + return; + } + + TaintRanges oldTaintRanges = new TaintRanges(); + TaintRanges newTaintRanges = new TaintRanges(); + + String srcValue; + String srcLoc = propagator.getSource(); + if (PARAMS_OBJECT.equals(srcLoc)) { + newTaintRanges = getTaintRanges(event.object); + srcValue = r.getTaintRangesBuilder().obj2String(event.object); + } else if (srcLoc.startsWith(PARAMS_PARAM)) { + int[] positions = (int[]) propagator.getSourcePosition(); + if (positions.length == 1) { + newTaintRanges = getTaintRanges(event.argumentArray[positions[0]]); + srcValue = r.getTaintRangesBuilder().obj2String(event.argumentArray[positions[0]]); + } else { + return; + } + } else { + // @TODO: concat O|P1 + return; + } + + int tgtHash; + String tgtValue; + String tgtLoc = propagator.getTarget(); + if (PARAMS_OBJECT.equals(tgtLoc)) { + tgtHash = System.identityHashCode(event.object); + tgtValue = r.getTaintRangesBuilder().obj2String(event.object); + } else if (PARAMS_RETURN.equals(tgtLoc)) { + tgtHash = System.identityHashCode(event.returnValue); + tgtValue = r.getTaintRangesBuilder().obj2String(event.returnValue); + } else if (srcLoc.startsWith(PARAMS_PARAM)) { + int[] positions = (int[]) propagator.getSourcePosition(); + tgtHash = System.identityHashCode(event.argumentArray[positions[0]]); + tgtValue = r.getTaintRangesBuilder().obj2String(event.argumentArray[positions[0]]); + } else { + return; + } + + TaintRanges tr = r.run(srcValue, tgtValue, event.argumentArray, oldTaintRanges, newTaintRanges); + event.targetRanges.add(new MethodEvent.MethodEventTargetRange(tgtHash, tgtValue, tr)); + EngineManager.TAINT_RANGES_POOL.add(tgtHash, tr); + } + private static void autoPropagator(AtomicInteger invokeIdSequence, MethodEvent event) { // 处理自动传播问题 // 检查污点池,判断是否存在命中的污点 diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/controller/impl/SourceImpl.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/controller/impl/SourceImpl.java index d2d7524cc..1b010a9e6 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/controller/impl/SourceImpl.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/controller/impl/SourceImpl.java @@ -97,6 +97,7 @@ private static void trackObject(TaintRangesBuilder tb, MethodEvent event, Object event.addTargetHash(hash); event.addTargetHashForRpc(obj.hashCode()); EngineManager.TAINT_POOL.get().add(obj); + EngineManager.TAINT_RANGES_POOL.add(hash, tr); } } diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommand.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommand.java new file mode 100644 index 000000000..ef3787ee9 --- /dev/null +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommand.java @@ -0,0 +1,22 @@ +package io.dongtai.iast.core.handler.hookpoint.vulscan.taintrange; + +import io.dongtai.iast.core.handler.hookpoint.vulscan.taintrange.TaintRangesBuilder.Command; + +import java.util.HashMap; +import java.util.Map; + +public class TaintCommand { + private static Map runnerMap = new HashMap(){{ + String STR_BUILD_INIT_1 = "java.lang.StringBuilder.(java.lang.String)"; + put(STR_BUILD_INIT_1, TaintCommandRunner.getInstance(STR_BUILD_INIT_1, Command.KEEP)); + String STR_BUILD_TO_STR = "java.lang.StringBuilder.toString()"; + put(STR_BUILD_TO_STR, TaintCommandRunner.getInstance(STR_BUILD_TO_STR, Command.KEEP)); + + String STR_BUILD_APPEND_1 = "java.lang.StringBuilder.append(java.lang.String)"; + put(STR_BUILD_APPEND_1, TaintCommandRunner.getInstance(STR_BUILD_APPEND_1, Command.APPEND)); + }}; + + public static TaintCommandRunner getCommand(String signature) { + return runnerMap.get(signature); + } +} diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommandRunner.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommandRunner.java new file mode 100644 index 000000000..1c55a0f7d --- /dev/null +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommandRunner.java @@ -0,0 +1,103 @@ +package io.dongtai.iast.core.handler.hookpoint.vulscan.taintrange; + +import io.dongtai.log.DongTaiLog; + +import java.util.ArrayList; +import java.util.List; + +public class TaintCommandRunner { + private String signature; + + private TaintRangesBuilder builder; + + private TaintRangesBuilder.Command command; + + private List params = new ArrayList(); + + private int paramsCount = 0; + + static class RunnerParam { + private int position; + private boolean isLiteral = false; + + public RunnerParam(String param) { + if (param.startsWith("P")) { + this.position = Integer.parseInt(param.substring(1)) - 1; + } else { + this.position = Integer.parseInt(param); + this.isLiteral = true; + } + } + + public int getParam(Object[] params) { + if (this.isLiteral) { + return this.position; + } + if (params == null) { + return 0; + } + + return (Integer) params[this.position]; + } + } + + public static TaintCommandRunner getInstance(String signature, TaintRangesBuilder.Command command) { + return getInstance(signature, command, null); + } + + public static TaintCommandRunner getInstance(String signature, TaintRangesBuilder.Command command, List params) { + try { + TaintCommandRunner r = new TaintCommandRunner(); + r.signature = signature; + r.builder = new TaintRangesBuilder(); + r.command = command; + if (params != null) { + r.paramsCount = params.size(); + for (String param : params) { + r.params.add(new RunnerParam(param)); + } + } + return r; + } catch (Exception e) { + return null; + } + } + + public TaintRangesBuilder getTaintRangesBuilder() { + return this.builder; + } + + public TaintRanges run(Object source, Object target, Object[]params, TaintRanges oldTaintRanges, TaintRanges newTaintRanges) { + int p1 = 0; + int p2 = 0; + int p3 = 0; + TaintRanges tr = new TaintRanges(); + + try { + if (this.paramsCount > 0) { + p1 = this.params.get(0).getParam(params); + } + if (this.paramsCount > 1) { + p2 = this.params.get(1).getParam(params); + } + if (this.paramsCount > 2) { + p3 = this.params.get(2).getParam(params); + } + } catch (Exception e) { + DongTaiLog.error(this.signature + " taint command parameters fetch failed: " + e.getMessage()); + return tr; + } + + switch (this.command) { + case KEEP: + this.builder.keep(tr, target, this.paramsCount, newTaintRanges); + break; + case APPEND: + this.builder.append(tr, target, oldTaintRanges, source, newTaintRanges, p1, p2, this.paramsCount); + default: + break; + } + + return tr; + } +} diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/utils/threadlocal/TaintRangesPool.java b/dongtai-core/src/main/java/io/dongtai/iast/core/utils/threadlocal/TaintRangesPool.java new file mode 100644 index 000000000..b530bbf39 --- /dev/null +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/utils/threadlocal/TaintRangesPool.java @@ -0,0 +1,21 @@ +package io.dongtai.iast.core.utils.threadlocal; + +import io.dongtai.iast.core.handler.hookpoint.vulscan.taintrange.TaintRanges; + +import java.util.HashMap; +import java.util.Map; + +public class TaintRangesPool extends ThreadLocal> { + @Override + protected Map initialValue() { + return new HashMap(); + } + + public void add(Integer hash, TaintRanges taintRanges) { + this.get().put(hash, taintRanges); + } + + public TaintRanges get(int hash) { + return this.get().get(hash); + } +} From d651bfbf8bf0cf596b4daeb2e2c0c1aacec14f62 Mon Sep 17 00:00:00 2001 From: lostsnow Date: Wed, 24 Aug 2022 11:56:37 +0800 Subject: [PATCH 08/19] add taint range keep/append methods --- .../vulscan/taintrange/TaintCommand.java | 141 ++++++++++++++++-- .../taintrange/TaintRangesBuilder.java | 52 +++---- 2 files changed, 156 insertions(+), 37 deletions(-) diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommand.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommand.java index ef3787ee9..361729757 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommand.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommand.java @@ -2,21 +2,140 @@ import io.dongtai.iast.core.handler.hookpoint.vulscan.taintrange.TaintRangesBuilder.Command; -import java.util.HashMap; -import java.util.Map; +import java.util.*; public class TaintCommand { - private static Map runnerMap = new HashMap(){{ - String STR_BUILD_INIT_1 = "java.lang.StringBuilder.(java.lang.String)"; - put(STR_BUILD_INIT_1, TaintCommandRunner.getInstance(STR_BUILD_INIT_1, Command.KEEP)); + public static TaintCommandRunner getCommand(String signature) { + return runnerMap.get(signature); + } + + private static final Map runnerMap = new HashMap() {{ + // KEEP String + String STR_INIT_1 = "java.lang.String.(java.lang.String)"; + put(STR_INIT_1, TaintCommandRunner.getInstance(STR_INIT_1, Command.KEEP)); + String STR_INIT_2 = "java.lang.String.(java.lang.StringBuilder)"; + put(STR_INIT_2, TaintCommandRunner.getInstance(STR_INIT_2, Command.KEEP)); + String STR_INIT_3 = "java.lang.String.(java.lang.StringBuffer)"; + put(STR_INIT_3, TaintCommandRunner.getInstance(STR_INIT_3, Command.KEEP)); + String STR_INIT_4 = "java.lang.String.(byte[],int,int)"; + put(STR_INIT_4, TaintCommandRunner.getInstance(STR_INIT_4, Command.KEEP)); + String STR_INIT_5 = "java.lang.String.(byte[],int,int,int)"; + put(STR_INIT_5, TaintCommandRunner.getInstance(STR_INIT_5, Command.KEEP)); + String STR_INIT_6 = "java.lang.String.(byte[],int,int,java.lang.String)"; + put(STR_INIT_6, TaintCommandRunner.getInstance(STR_INIT_6, Command.KEEP)); + String STR_INIT_7 = "java.lang.String.(char[])"; + put(STR_INIT_7, TaintCommandRunner.getInstance(STR_INIT_7, Command.KEEP)); + String STR_INIT_8 = "java.lang.String.(byte[],java.nio.charset.Charset)"; + put(STR_INIT_8, TaintCommandRunner.getInstance(STR_INIT_8, Command.KEEP)); + String STR_INIT_9 = "java.lang.String.(byte[],byte)"; // Java-17 + put(STR_INIT_9, TaintCommandRunner.getInstance(STR_INIT_9, Command.KEEP)); + String STR_LOWER = "java.lang.String.toLowerCase(java.util.Locale)"; + put(STR_LOWER, TaintCommandRunner.getInstance(STR_LOWER, Command.KEEP)); + String STR_UPPER = "java.lang.String.toUpperCase(java.util.Locale)"; + put(STR_UPPER, TaintCommandRunner.getInstance(STR_UPPER, Command.KEEP)); + String STR_GET_BS_1 = "java.lang.String.getBytes()"; + put(STR_GET_BS_1, TaintCommandRunner.getInstance(STR_GET_BS_1, Command.KEEP)); + String STR_GET_BS_2 = "java.lang.String.getBytes(java.lang.String)"; + put(STR_GET_BS_2, TaintCommandRunner.getInstance(STR_GET_BS_2, Command.KEEP)); + String STR_GET_BS_3 = "java.lang.String.getBytes(java.nio.charset.Charset)"; + put(STR_GET_BS_3, TaintCommandRunner.getInstance(STR_GET_BS_3, Command.KEEP)); + String STR_TO_CA = "java.lang.String.toCharArray()"; + put(STR_TO_CA, TaintCommandRunner.getInstance(STR_TO_CA, Command.KEEP)); + + // KEEP StringBuilder String STR_BUILD_TO_STR = "java.lang.StringBuilder.toString()"; put(STR_BUILD_TO_STR, TaintCommandRunner.getInstance(STR_BUILD_TO_STR, Command.KEEP)); + String STR_BUILD_INIT_1 = "java.lang.StringBuilder.(java.lang.String)"; + put(STR_BUILD_INIT_1, TaintCommandRunner.getInstance(STR_BUILD_INIT_1, Command.KEEP)); + String STR_BUILD_INIT_2 = "java.lang.StringBuilder.(java.lang.CharSequence)"; + put(STR_BUILD_INIT_2, TaintCommandRunner.getInstance(STR_BUILD_INIT_2, Command.KEEP)); - String STR_BUILD_APPEND_1 = "java.lang.StringBuilder.append(java.lang.String)"; - put(STR_BUILD_APPEND_1, TaintCommandRunner.getInstance(STR_BUILD_APPEND_1, Command.APPEND)); - }}; + // KEEP StringBuffer + String STR_BUFF_TO_STR = "java.lang.StringBuffer.toString()"; + put(STR_BUFF_TO_STR, TaintCommandRunner.getInstance(STR_BUFF_TO_STR, Command.KEEP)); + String STR_BUFF_INIT_1 = "java.lang.StringBuffer.(java.lang.String)"; + put(STR_BUFF_INIT_1, TaintCommandRunner.getInstance(STR_BUFF_INIT_1, Command.KEEP)); + String STR_BUFF_INIT_2 = "java.lang.StringBuffer.(java.lang.CharSequence)"; + put(STR_BUFF_INIT_2, TaintCommandRunner.getInstance(STR_BUFF_INIT_2, Command.KEEP)); - public static TaintCommandRunner getCommand(String signature) { - return runnerMap.get(signature); - } + // KEEP ByteArrayOutputStream + String BAOS_TO_BA = "java.io.ByteArrayOutputStream.toByteArray()"; + put(BAOS_TO_BA, TaintCommandRunner.getInstance(BAOS_TO_BA, Command.KEEP)); + String BAOS_TO_STR_1 = "java.io.ByteArrayOutputStream.toString()"; + put(BAOS_TO_STR_1, TaintCommandRunner.getInstance(BAOS_TO_STR_1, Command.KEEP)); + String BAOS_TO_STR_2 = "java.io.ByteArrayOutputStream.toString(java.lang.String)"; + put(BAOS_TO_STR_2, TaintCommandRunner.getInstance(BAOS_TO_STR_2, Command.KEEP)); + String BAOS_TO_STR_3 = "java.io.ByteArrayOutputStream.toString(int)"; + put(BAOS_TO_STR_3, TaintCommandRunner.getInstance(BAOS_TO_STR_3, Command.KEEP)); + String BAOS_TO_STR_4 = "java.io.ByteArrayOutputStream.toString(java.nio.charset.Charset)"; + put(BAOS_TO_STR_4, TaintCommandRunner.getInstance(BAOS_TO_STR_4, Command.KEEP)); + + // KEEP StringConcatHelper + String STR_CONCAT_HP_NEW_STR_1 = "java.lang.StringConcatHelper.newString(byte[],int,byte)"; // Java 9-11 + put(STR_CONCAT_HP_NEW_STR_1, TaintCommandRunner.getInstance(STR_CONCAT_HP_NEW_STR_1, Command.KEEP)); + String STR_CONCAT_HP_NEW_STR_2 = "java.lang.StringConcatHelper.newString(byte[],long)"; // Java 12+, up to 14 + put(STR_CONCAT_HP_NEW_STR_2, TaintCommandRunner.getInstance(STR_CONCAT_HP_NEW_STR_2, Command.KEEP)); + + // KEEP StringWriter + String STR_WR_TO_STR = "java.io.StringWriter.toString()"; + put(STR_WR_TO_STR, TaintCommandRunner.getInstance(STR_WR_TO_STR, Command.KEEP)); + + // APPEND String + String STR_INIT_APD_1 = "java.lang.String.(char[],int,int)"; + put(STR_INIT_APD_1, TaintCommandRunner.getInstance(STR_INIT_APD_1, Command.APPEND, Arrays.asList("P2", "P3", "0"))); + String STR_INIT_APD = "java.lang.String.(char[],int,int,boolean)"; // in IBM JDK8 split() + put(STR_INIT_APD, TaintCommandRunner.getInstance(STR_INIT_APD, Command.APPEND, Arrays.asList("P2", "P3", "0"))); + + // APPEND StringBuilder + String STR_BUILD_APD_1 = "java.lang.StringBuilder.append(java.lang.String)"; + put(STR_BUILD_APD_1, TaintCommandRunner.getInstance(STR_BUILD_APD_1, Command.APPEND)); + String STR_BUILD_APD_2 = "java.lang.StringBuilder.append(java.lang.StringBuffer)"; + put(STR_BUILD_APD_2, TaintCommandRunner.getInstance(STR_BUILD_APD_2, Command.APPEND)); + String STR_BUILD_APD_3 = "java.lang.StringBuilder.append(java.lang.CharSequence)"; + put(STR_BUILD_APD_3, TaintCommandRunner.getInstance(STR_BUILD_APD_3, Command.APPEND)); + String STR_BUILD_APD_4 = "java.lang.StringBuilder.append(java.lang.CharSequence,int,int)"; + put(STR_BUILD_APD_4, TaintCommandRunner.getInstance(STR_BUILD_APD_4, Command.APPEND, Arrays.asList("P2", "P3"))); + String STR_BUILD_APD_5 = "java.lang.StringBuilder.append(char[],int,int)"; + put(STR_BUILD_APD_5, TaintCommandRunner.getInstance(STR_BUILD_APD_5, Command.APPEND, Arrays.asList("P2", "P3", "0"))); + + // APPEND AbstractStringBuilder + String ABS_STR_BUILD_APD_1 = "java.lang.AbstractStringBuilder.append(java.lang.String)"; + put(ABS_STR_BUILD_APD_1, TaintCommandRunner.getInstance(ABS_STR_BUILD_APD_1, Command.APPEND)); + + // APPEND StringBuffer + String STR_BUFF_APD_1 = "java.lang.StringBuffer.append(java.lang.String)"; + put(STR_BUFF_APD_1, TaintCommandRunner.getInstance(STR_BUFF_APD_1, Command.APPEND)); + String STR_BUFF_APD_2 = "java.lang.StringBuffer.append(java.lang.StringBuffer)"; + put(STR_BUFF_APD_2, TaintCommandRunner.getInstance(STR_BUFF_APD_2, Command.APPEND)); + String STR_BUFF_APD_3 = "java.lang.StringBuffer.append(char[])"; + put(STR_BUFF_APD_3, TaintCommandRunner.getInstance(STR_BUFF_APD_3, Command.APPEND)); + String STR_BUFF_APD_4 = "java.lang.StringBuffer.append(java.lang.CharSequence)"; + put(STR_BUFF_APD_4, TaintCommandRunner.getInstance(STR_BUFF_APD_4, Command.APPEND)); + String STR_BUFF_APD_5 = "java.lang.StringBuffer.append(java.lang.CharSequence,int,int)"; + put(STR_BUFF_APD_5, TaintCommandRunner.getInstance(STR_BUFF_APD_5, Command.APPEND, Arrays.asList("P2", "P3"))); + String STR_BUFF_APD_6 = "java.lang.StringBuffer.append(char[],int,int)"; + put(STR_BUFF_APD_6, TaintCommandRunner.getInstance(STR_BUFF_APD_6, Command.APPEND, Arrays.asList("P2", "P3", "0"))); + + // APPEND ByteArrayOutputStream + String BAOS_WRITE = "java.io.ByteArrayOutputStream.toString(java.nio.charset.Charset)"; + put(BAOS_WRITE, TaintCommandRunner.getInstance(BAOS_WRITE, Command.APPEND, Arrays.asList("P2", "P3"))); + + // APPEND StringLatin1/StringUTF16 + String STR_NEW_STR_1 = "java.lang.StringLatin1.newString(byte[],int,int)"; + put(STR_NEW_STR_1, TaintCommandRunner.getInstance(STR_NEW_STR_1, Command.APPEND, Arrays.asList("P2", "P3", "0"))); + String STR_NEW_STR_2 = "java.lang.StringUTF16.newString(byte[],int,int)"; + put(STR_NEW_STR_2, TaintCommandRunner.getInstance(STR_NEW_STR_2, Command.APPEND, Arrays.asList("P2", "P3", "0"))); + + // APPEND StringWriter + String STR_WR_WRITE_1 = "java.io.StringWriter.write(char[],int,int)"; + put(STR_WR_WRITE_1, TaintCommandRunner.getInstance(STR_WR_WRITE_1, Command.APPEND, Arrays.asList("P2", "P3"))); + String STR_WR_WRITE_2 = "java.io.StringWriter.write(java.lang.String)"; + put(STR_WR_WRITE_2, TaintCommandRunner.getInstance(STR_WR_WRITE_2, Command.APPEND)); + String STR_WR_WRITE_3 = "java.io.StringWriter.write(java.lang.String,int,int)"; + put(STR_WR_WRITE_3, TaintCommandRunner.getInstance(STR_WR_WRITE_3, Command.APPEND, Arrays.asList("P2", "P3"))); + + // APPEND apache ByteArrayOutputStream + String APACHE_BAOS_WRITE = "org.apache.commons.io.output.ByteArrayOutputStream.write(byte[],int,int)"; + put(APACHE_BAOS_WRITE, TaintCommandRunner.getInstance(APACHE_BAOS_WRITE, Command.APPEND, Arrays.asList("P2", "P3"))); + }}; } diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesBuilder.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesBuilder.java index 73b3055db..60634b83f 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesBuilder.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesBuilder.java @@ -17,45 +17,45 @@ public enum Command { TRIM_LEFT, } - public void keep(TaintRanges taintRanges, Object target, int argC, TaintRanges tgtTaintRanges) { + public void keep(TaintRanges taintRanges, Object target, int argC, TaintRanges newTaintRanges) { if (argC == 0) { int length = this.getLength(target); if (length > 0) { - for (TaintRange taintRange : tgtTaintRanges.getTaintRanges()) { + for (TaintRange taintRange : newTaintRanges.getTaintRanges()) { if (taintRange.getStart() < length && taintRange.getStop() > length) { taintRange.setStop(length); } taintRanges.add(taintRange); } } else { - taintRanges.addAll(tgtTaintRanges); + taintRanges.addAll(newTaintRanges); } taintRanges.merge(); } } - public void append(TaintRanges taintRanges, Object target, TaintRanges srcTaintRanges, - Object source, TaintRanges tgtTaintRanges, int p1, int p2, int argC) { + public void append(TaintRanges taintRanges, Object target, TaintRanges oldTaintRanges, + Object source, TaintRanges newTaintRanges, int p1, int p2, int argC) { int length = this.getLength(target); switch (argC) { case 0: // src.append(tgt) - tgtTaintRanges.shift(length - this.getLength(source)); - taintRanges.addAll(srcTaintRanges); - taintRanges.addAll(tgtTaintRanges); + newTaintRanges.shift(length - this.getLength(source)); + taintRanges.addAll(oldTaintRanges); + taintRanges.addAll(newTaintRanges); break; case 2: - tgtTaintRanges.trim(p1, p2); - tgtTaintRanges.shift(length - (p2 - p1)); - taintRanges.addAll(srcTaintRanges); - taintRanges.addAll(tgtTaintRanges); + newTaintRanges.trim(p1, p2); + newTaintRanges.shift(length - (p2 - p1)); + taintRanges.addAll(oldTaintRanges); + taintRanges.addAll(newTaintRanges); break; case 3: - tgtTaintRanges.trim(p1, p1 + p2); - tgtTaintRanges.shift(length - p2); - taintRanges.addAll(srcTaintRanges); - taintRanges.addAll(tgtTaintRanges); + newTaintRanges.trim(p1, p1 + p2); + newTaintRanges.shift(length - p2); + taintRanges.addAll(oldTaintRanges); + taintRanges.addAll(newTaintRanges); break; default: return; @@ -63,23 +63,23 @@ public void append(TaintRanges taintRanges, Object target, TaintRanges srcTaintR taintRanges.merge(); } - public void subset(TaintRanges taintRanges, TaintRanges srcTaintRanges, Object source, TaintRanges tgtTaintRanges, int p1, int p2, int p3, int argC) { + public void subset(TaintRanges taintRanges, TaintRanges oldTaintRanges, Object source, TaintRanges newTaintRanges, int p1, int p2, int p3, int argC) { int length = this.getLength(source); switch (argC) { case 1: - tgtTaintRanges.trim(p1, length); - taintRanges.addAll(tgtTaintRanges); + newTaintRanges.trim(p1, length); + taintRanges.addAll(newTaintRanges); break; case 2: - tgtTaintRanges.trim(p1, p2); - taintRanges.addAll(tgtTaintRanges); + newTaintRanges.trim(p1, p2); + taintRanges.addAll(newTaintRanges); break; case 3: - srcTaintRanges.clear(p3, (p3 + p2) - p1); - tgtTaintRanges.trim(p1, p2); - tgtTaintRanges.shift(p3); - taintRanges.addAll(srcTaintRanges); - taintRanges.addAll(tgtTaintRanges); + oldTaintRanges.clear(p3, (p3 + p2) - p1); + newTaintRanges.trim(p1, p2); + newTaintRanges.shift(p3); + taintRanges.addAll(oldTaintRanges); + taintRanges.addAll(newTaintRanges); break; default: return; From abb62e3c1d1ff69f11f8f4681118524aa664ebfb Mon Sep 17 00:00:00 2001 From: lostsnow Date: Thu, 25 Aug 2022 14:21:44 +0800 Subject: [PATCH 09/19] taint range subset, refactor dir --- .../handler/hookpoint/SpyDispatcherImpl.java | 2 +- .../handler/hookpoint/api/GetApiThread.java | 8 +- .../controller/impl/PropagatorImpl.java | 85 ++++--- .../hookpoint/controller/impl/SourceImpl.java | 4 +- .../vulscan/taintrange/TaintCommand.java | 149 +----------- .../taintrange/TaintCommandRunner.java | 217 +++++++++++++++++- .../taintrange/TaintRangesBuilder.java | 77 +++---- .../taintrange/TaintRangeBuilderTrimTest.java | 6 +- 8 files changed, 318 insertions(+), 230 deletions(-) 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 4f32e53e1..9d771a116 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 @@ -501,7 +501,7 @@ public boolean collectMethodPool(Object instance, Object[] argumentArray, Object } } } catch (Exception e) { - DongTaiLog.error(e); + DongTaiLog.error("collect method pool failed: " + e.toString(), e); } finally { EngineManager.turnOnDongTai(); } diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/api/GetApiThread.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/api/GetApiThread.java index 3576a4886..43bb55388 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/api/GetApiThread.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/api/GetApiThread.java @@ -2,6 +2,7 @@ import io.dongtai.iast.core.bytecode.enhance.plugin.spring.SpringApplicationImpl; import io.dongtai.log.DongTaiLog; + import java.lang.reflect.InvocationTargetException; import java.util.Map; @@ -15,14 +16,17 @@ public GetApiThread(Object applicationContext) { @Override public void run() { + if (SpringApplicationImpl.getAPI == null) { + return; + } Map invoke = null; try { invoke = (Map) SpringApplicationImpl.getAPI.invoke(null, applicationContext); ApiReport.sendReport(invoke); } catch (IllegalAccessException e) { - DongTaiLog.error(e); + DongTaiLog.error("GetApiThread failed: " + e.toString(), e); } catch (InvocationTargetException e) { - DongTaiLog.error(e); + DongTaiLog.error("GetApiThread failed: " + e.toString(), e); } finally { SpringApplicationImpl.isSend = true; } 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 abe223332..6a8921e7b 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 @@ -167,50 +167,75 @@ private static TaintRanges getTaintRanges(Object obj) { } private static void trackTaintRange(IastPropagatorModel propagator, MethodEvent event) { - TaintCommandRunner r = TaintCommand.getCommand(event.signature); - if (r == null) { - return; - } + TaintCommandRunner r = TaintCommandRunner.getCommandRunner(event.signature); TaintRanges oldTaintRanges = new TaintRanges(); - TaintRanges newTaintRanges = new TaintRanges(); - - String srcValue; - String srcLoc = propagator.getSource(); - if (PARAMS_OBJECT.equals(srcLoc)) { - newTaintRanges = getTaintRanges(event.object); - srcValue = r.getTaintRangesBuilder().obj2String(event.object); - } else if (srcLoc.startsWith(PARAMS_PARAM)) { - int[] positions = (int[]) propagator.getSourcePosition(); - if (positions.length == 1) { - newTaintRanges = getTaintRanges(event.argumentArray[positions[0]]); - srcValue = r.getTaintRangesBuilder().obj2String(event.argumentArray[positions[0]]); - } else { - return; + TaintRanges srcTaintRanges = new TaintRanges(); + + String srcValue = null; + if (r != null) { + String srcLoc = propagator.getSource(); + if (PARAMS_OBJECT.equals(srcLoc)) { + srcTaintRanges = getTaintRanges(event.object); + srcValue = TaintRangesBuilder.obj2String(event.object); + } else if (srcLoc.startsWith("O|P")) { + oldTaintRanges = getTaintRanges(event.object); + int[] positions = (int[]) propagator.getSourcePosition(); + if (positions.length == 1 && event.argumentArray.length >= positions[0]) { + srcTaintRanges = getTaintRanges(event.argumentArray[positions[0]]); + srcValue = TaintRangesBuilder.obj2String(event.argumentArray[positions[0]]); + } + } else if (srcLoc.startsWith(PARAMS_PARAM)) { + // invalid policy + if (srcLoc.contains(CONDITION_OR) || srcLoc.contains(CONDITION_AND)) { + return; + } + int[] positions = (int[]) propagator.getSourcePosition(); + if (positions.length == 1 && event.argumentArray.length >= positions[0]) { + srcTaintRanges = getTaintRanges(event.argumentArray[positions[0]]); + srcValue = TaintRangesBuilder.obj2String(event.argumentArray[positions[0]]); + } } - } else { - // @TODO: concat O|P1 - return; } int tgtHash; String tgtValue; + Object tgt; String tgtLoc = propagator.getTarget(); if (PARAMS_OBJECT.equals(tgtLoc)) { - tgtHash = System.identityHashCode(event.object); - tgtValue = r.getTaintRangesBuilder().obj2String(event.object); + tgt = event.object; + tgtHash = System.identityHashCode(tgt); + tgtValue = TaintRangesBuilder.obj2String(tgt); + oldTaintRanges = getTaintRanges(tgt); } else if (PARAMS_RETURN.equals(tgtLoc)) { - tgtHash = System.identityHashCode(event.returnValue); - tgtValue = r.getTaintRangesBuilder().obj2String(event.returnValue); - } else if (srcLoc.startsWith(PARAMS_PARAM)) { - int[] positions = (int[]) propagator.getSourcePosition(); - tgtHash = System.identityHashCode(event.argumentArray[positions[0]]); - tgtValue = r.getTaintRangesBuilder().obj2String(event.argumentArray[positions[0]]); + tgt = event.returnValue; + tgtHash = System.identityHashCode(tgt); + tgtValue = TaintRangesBuilder.obj2String(tgt); + } else if (tgtLoc.startsWith(PARAMS_PARAM)) { + // invalid policy + if (tgtLoc.contains(CONDITION_OR) || tgtLoc.contains(CONDITION_AND)) { + return; + } + int[] positions = (int[]) propagator.getTargetPosition(); + if (positions.length != 1 || event.argumentArray.length < positions[0]) { + // target can only have one parameter + return; + } + tgt = event.argumentArray[positions[0]]; + tgtHash = System.identityHashCode(tgt); + tgtValue = TaintRangesBuilder.obj2String(tgt); + oldTaintRanges = getTaintRanges(tgt); } else { + // invalid policy return; } - TaintRanges tr = r.run(srcValue, tgtValue, event.argumentArray, oldTaintRanges, newTaintRanges); + TaintRanges tr; + if (r != null && srcValue != null) { + tr = r.run(srcValue, tgtValue, event.argumentArray, oldTaintRanges, srcTaintRanges); + } else { + tr = new TaintRanges(new TaintRange(0, TaintRangesBuilder.getLength(tgt))); + } event.targetRanges.add(new MethodEvent.MethodEventTargetRange(tgtHash, tgtValue, tr)); EngineManager.TAINT_RANGES_POOL.add(tgtHash, tr); } diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/controller/impl/SourceImpl.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/controller/impl/SourceImpl.java index 1b010a9e6..54180d67e 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/controller/impl/SourceImpl.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/controller/impl/SourceImpl.java @@ -86,13 +86,13 @@ private static void trackObject(TaintRangesBuilder tb, MethodEvent event, Object } else if ("java.util.Optional".equals(obj.getClass().getName())) { trackOptional(tb, event, obj, depth); } else { - int len = tb.getLength(obj); + int len = TaintRangesBuilder.getLength(obj); if (len == 0) { return; } TaintRanges tr = new TaintRanges(new TaintRange(0, len)); - event.targetRanges.add(new MethodEvent.MethodEventTargetRange(hash, tb.obj2String(obj), tr)); + event.targetRanges.add(new MethodEvent.MethodEventTargetRange(hash, TaintRangesBuilder.obj2String(obj), tr)); EngineManager.TAINT_HASH_CODES.get().add(hash); event.addTargetHash(hash); event.addTargetHashForRpc(obj.hashCode()); diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommand.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommand.java index 361729757..6647b2d73 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommand.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommand.java @@ -1,141 +1,14 @@ package io.dongtai.iast.core.handler.hookpoint.vulscan.taintrange; -import io.dongtai.iast.core.handler.hookpoint.vulscan.taintrange.TaintRangesBuilder.Command; - -import java.util.*; - -public class TaintCommand { - public static TaintCommandRunner getCommand(String signature) { - return runnerMap.get(signature); - } - - private static final Map runnerMap = new HashMap() {{ - // KEEP String - String STR_INIT_1 = "java.lang.String.(java.lang.String)"; - put(STR_INIT_1, TaintCommandRunner.getInstance(STR_INIT_1, Command.KEEP)); - String STR_INIT_2 = "java.lang.String.(java.lang.StringBuilder)"; - put(STR_INIT_2, TaintCommandRunner.getInstance(STR_INIT_2, Command.KEEP)); - String STR_INIT_3 = "java.lang.String.(java.lang.StringBuffer)"; - put(STR_INIT_3, TaintCommandRunner.getInstance(STR_INIT_3, Command.KEEP)); - String STR_INIT_4 = "java.lang.String.(byte[],int,int)"; - put(STR_INIT_4, TaintCommandRunner.getInstance(STR_INIT_4, Command.KEEP)); - String STR_INIT_5 = "java.lang.String.(byte[],int,int,int)"; - put(STR_INIT_5, TaintCommandRunner.getInstance(STR_INIT_5, Command.KEEP)); - String STR_INIT_6 = "java.lang.String.(byte[],int,int,java.lang.String)"; - put(STR_INIT_6, TaintCommandRunner.getInstance(STR_INIT_6, Command.KEEP)); - String STR_INIT_7 = "java.lang.String.(char[])"; - put(STR_INIT_7, TaintCommandRunner.getInstance(STR_INIT_7, Command.KEEP)); - String STR_INIT_8 = "java.lang.String.(byte[],java.nio.charset.Charset)"; - put(STR_INIT_8, TaintCommandRunner.getInstance(STR_INIT_8, Command.KEEP)); - String STR_INIT_9 = "java.lang.String.(byte[],byte)"; // Java-17 - put(STR_INIT_9, TaintCommandRunner.getInstance(STR_INIT_9, Command.KEEP)); - String STR_LOWER = "java.lang.String.toLowerCase(java.util.Locale)"; - put(STR_LOWER, TaintCommandRunner.getInstance(STR_LOWER, Command.KEEP)); - String STR_UPPER = "java.lang.String.toUpperCase(java.util.Locale)"; - put(STR_UPPER, TaintCommandRunner.getInstance(STR_UPPER, Command.KEEP)); - String STR_GET_BS_1 = "java.lang.String.getBytes()"; - put(STR_GET_BS_1, TaintCommandRunner.getInstance(STR_GET_BS_1, Command.KEEP)); - String STR_GET_BS_2 = "java.lang.String.getBytes(java.lang.String)"; - put(STR_GET_BS_2, TaintCommandRunner.getInstance(STR_GET_BS_2, Command.KEEP)); - String STR_GET_BS_3 = "java.lang.String.getBytes(java.nio.charset.Charset)"; - put(STR_GET_BS_3, TaintCommandRunner.getInstance(STR_GET_BS_3, Command.KEEP)); - String STR_TO_CA = "java.lang.String.toCharArray()"; - put(STR_TO_CA, TaintCommandRunner.getInstance(STR_TO_CA, Command.KEEP)); - - // KEEP StringBuilder - String STR_BUILD_TO_STR = "java.lang.StringBuilder.toString()"; - put(STR_BUILD_TO_STR, TaintCommandRunner.getInstance(STR_BUILD_TO_STR, Command.KEEP)); - String STR_BUILD_INIT_1 = "java.lang.StringBuilder.(java.lang.String)"; - put(STR_BUILD_INIT_1, TaintCommandRunner.getInstance(STR_BUILD_INIT_1, Command.KEEP)); - String STR_BUILD_INIT_2 = "java.lang.StringBuilder.(java.lang.CharSequence)"; - put(STR_BUILD_INIT_2, TaintCommandRunner.getInstance(STR_BUILD_INIT_2, Command.KEEP)); - - // KEEP StringBuffer - String STR_BUFF_TO_STR = "java.lang.StringBuffer.toString()"; - put(STR_BUFF_TO_STR, TaintCommandRunner.getInstance(STR_BUFF_TO_STR, Command.KEEP)); - String STR_BUFF_INIT_1 = "java.lang.StringBuffer.(java.lang.String)"; - put(STR_BUFF_INIT_1, TaintCommandRunner.getInstance(STR_BUFF_INIT_1, Command.KEEP)); - String STR_BUFF_INIT_2 = "java.lang.StringBuffer.(java.lang.CharSequence)"; - put(STR_BUFF_INIT_2, TaintCommandRunner.getInstance(STR_BUFF_INIT_2, Command.KEEP)); - - // KEEP ByteArrayOutputStream - String BAOS_TO_BA = "java.io.ByteArrayOutputStream.toByteArray()"; - put(BAOS_TO_BA, TaintCommandRunner.getInstance(BAOS_TO_BA, Command.KEEP)); - String BAOS_TO_STR_1 = "java.io.ByteArrayOutputStream.toString()"; - put(BAOS_TO_STR_1, TaintCommandRunner.getInstance(BAOS_TO_STR_1, Command.KEEP)); - String BAOS_TO_STR_2 = "java.io.ByteArrayOutputStream.toString(java.lang.String)"; - put(BAOS_TO_STR_2, TaintCommandRunner.getInstance(BAOS_TO_STR_2, Command.KEEP)); - String BAOS_TO_STR_3 = "java.io.ByteArrayOutputStream.toString(int)"; - put(BAOS_TO_STR_3, TaintCommandRunner.getInstance(BAOS_TO_STR_3, Command.KEEP)); - String BAOS_TO_STR_4 = "java.io.ByteArrayOutputStream.toString(java.nio.charset.Charset)"; - put(BAOS_TO_STR_4, TaintCommandRunner.getInstance(BAOS_TO_STR_4, Command.KEEP)); - - // KEEP StringConcatHelper - String STR_CONCAT_HP_NEW_STR_1 = "java.lang.StringConcatHelper.newString(byte[],int,byte)"; // Java 9-11 - put(STR_CONCAT_HP_NEW_STR_1, TaintCommandRunner.getInstance(STR_CONCAT_HP_NEW_STR_1, Command.KEEP)); - String STR_CONCAT_HP_NEW_STR_2 = "java.lang.StringConcatHelper.newString(byte[],long)"; // Java 12+, up to 14 - put(STR_CONCAT_HP_NEW_STR_2, TaintCommandRunner.getInstance(STR_CONCAT_HP_NEW_STR_2, Command.KEEP)); - - // KEEP StringWriter - String STR_WR_TO_STR = "java.io.StringWriter.toString()"; - put(STR_WR_TO_STR, TaintCommandRunner.getInstance(STR_WR_TO_STR, Command.KEEP)); - - // APPEND String - String STR_INIT_APD_1 = "java.lang.String.(char[],int,int)"; - put(STR_INIT_APD_1, TaintCommandRunner.getInstance(STR_INIT_APD_1, Command.APPEND, Arrays.asList("P2", "P3", "0"))); - String STR_INIT_APD = "java.lang.String.(char[],int,int,boolean)"; // in IBM JDK8 split() - put(STR_INIT_APD, TaintCommandRunner.getInstance(STR_INIT_APD, Command.APPEND, Arrays.asList("P2", "P3", "0"))); - - // APPEND StringBuilder - String STR_BUILD_APD_1 = "java.lang.StringBuilder.append(java.lang.String)"; - put(STR_BUILD_APD_1, TaintCommandRunner.getInstance(STR_BUILD_APD_1, Command.APPEND)); - String STR_BUILD_APD_2 = "java.lang.StringBuilder.append(java.lang.StringBuffer)"; - put(STR_BUILD_APD_2, TaintCommandRunner.getInstance(STR_BUILD_APD_2, Command.APPEND)); - String STR_BUILD_APD_3 = "java.lang.StringBuilder.append(java.lang.CharSequence)"; - put(STR_BUILD_APD_3, TaintCommandRunner.getInstance(STR_BUILD_APD_3, Command.APPEND)); - String STR_BUILD_APD_4 = "java.lang.StringBuilder.append(java.lang.CharSequence,int,int)"; - put(STR_BUILD_APD_4, TaintCommandRunner.getInstance(STR_BUILD_APD_4, Command.APPEND, Arrays.asList("P2", "P3"))); - String STR_BUILD_APD_5 = "java.lang.StringBuilder.append(char[],int,int)"; - put(STR_BUILD_APD_5, TaintCommandRunner.getInstance(STR_BUILD_APD_5, Command.APPEND, Arrays.asList("P2", "P3", "0"))); - - // APPEND AbstractStringBuilder - String ABS_STR_BUILD_APD_1 = "java.lang.AbstractStringBuilder.append(java.lang.String)"; - put(ABS_STR_BUILD_APD_1, TaintCommandRunner.getInstance(ABS_STR_BUILD_APD_1, Command.APPEND)); - - // APPEND StringBuffer - String STR_BUFF_APD_1 = "java.lang.StringBuffer.append(java.lang.String)"; - put(STR_BUFF_APD_1, TaintCommandRunner.getInstance(STR_BUFF_APD_1, Command.APPEND)); - String STR_BUFF_APD_2 = "java.lang.StringBuffer.append(java.lang.StringBuffer)"; - put(STR_BUFF_APD_2, TaintCommandRunner.getInstance(STR_BUFF_APD_2, Command.APPEND)); - String STR_BUFF_APD_3 = "java.lang.StringBuffer.append(char[])"; - put(STR_BUFF_APD_3, TaintCommandRunner.getInstance(STR_BUFF_APD_3, Command.APPEND)); - String STR_BUFF_APD_4 = "java.lang.StringBuffer.append(java.lang.CharSequence)"; - put(STR_BUFF_APD_4, TaintCommandRunner.getInstance(STR_BUFF_APD_4, Command.APPEND)); - String STR_BUFF_APD_5 = "java.lang.StringBuffer.append(java.lang.CharSequence,int,int)"; - put(STR_BUFF_APD_5, TaintCommandRunner.getInstance(STR_BUFF_APD_5, Command.APPEND, Arrays.asList("P2", "P3"))); - String STR_BUFF_APD_6 = "java.lang.StringBuffer.append(char[],int,int)"; - put(STR_BUFF_APD_6, TaintCommandRunner.getInstance(STR_BUFF_APD_6, Command.APPEND, Arrays.asList("P2", "P3", "0"))); - - // APPEND ByteArrayOutputStream - String BAOS_WRITE = "java.io.ByteArrayOutputStream.toString(java.nio.charset.Charset)"; - put(BAOS_WRITE, TaintCommandRunner.getInstance(BAOS_WRITE, Command.APPEND, Arrays.asList("P2", "P3"))); - - // APPEND StringLatin1/StringUTF16 - String STR_NEW_STR_1 = "java.lang.StringLatin1.newString(byte[],int,int)"; - put(STR_NEW_STR_1, TaintCommandRunner.getInstance(STR_NEW_STR_1, Command.APPEND, Arrays.asList("P2", "P3", "0"))); - String STR_NEW_STR_2 = "java.lang.StringUTF16.newString(byte[],int,int)"; - put(STR_NEW_STR_2, TaintCommandRunner.getInstance(STR_NEW_STR_2, Command.APPEND, Arrays.asList("P2", "P3", "0"))); - - // APPEND StringWriter - String STR_WR_WRITE_1 = "java.io.StringWriter.write(char[],int,int)"; - put(STR_WR_WRITE_1, TaintCommandRunner.getInstance(STR_WR_WRITE_1, Command.APPEND, Arrays.asList("P2", "P3"))); - String STR_WR_WRITE_2 = "java.io.StringWriter.write(java.lang.String)"; - put(STR_WR_WRITE_2, TaintCommandRunner.getInstance(STR_WR_WRITE_2, Command.APPEND)); - String STR_WR_WRITE_3 = "java.io.StringWriter.write(java.lang.String,int,int)"; - put(STR_WR_WRITE_3, TaintCommandRunner.getInstance(STR_WR_WRITE_3, Command.APPEND, Arrays.asList("P2", "P3"))); - - // APPEND apache ByteArrayOutputStream - String APACHE_BAOS_WRITE = "org.apache.commons.io.output.ByteArrayOutputStream.write(byte[],int,int)"; - put(APACHE_BAOS_WRITE, TaintCommandRunner.getInstance(APACHE_BAOS_WRITE, Command.APPEND, Arrays.asList("P2", "P3"))); - }}; +public enum TaintCommand { + KEEP, + APPEND, + SUBSET, + INSERT, + REMOVE, + REPLACE, + CONCAT, + TRIM, + TRIM_RIGHT, + TRIM_LEFT, } diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommandRunner.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommandRunner.java index 1c55a0f7d..0338e8136 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommandRunner.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommandRunner.java @@ -2,15 +2,14 @@ import io.dongtai.log.DongTaiLog; -import java.util.ArrayList; -import java.util.List; +import java.util.*; public class TaintCommandRunner { private String signature; private TaintRangesBuilder builder; - private TaintRangesBuilder.Command command; + private TaintCommand command; private List params = new ArrayList(); @@ -41,11 +40,11 @@ public int getParam(Object[] params) { } } - public static TaintCommandRunner getInstance(String signature, TaintRangesBuilder.Command command) { - return getInstance(signature, command, null); + public static TaintCommandRunner create(String signature, TaintCommand command) { + return create(signature, command, null); } - public static TaintCommandRunner getInstance(String signature, TaintRangesBuilder.Command command, List params) { + public static TaintCommandRunner create(String signature, TaintCommand command, List params) { try { TaintCommandRunner r = new TaintCommandRunner(); r.signature = signature; @@ -67,7 +66,7 @@ public TaintRangesBuilder getTaintRangesBuilder() { return this.builder; } - public TaintRanges run(Object source, Object target, Object[]params, TaintRanges oldTaintRanges, TaintRanges newTaintRanges) { + public TaintRanges run(Object source, Object target, Object[] params, TaintRanges oldTaintRanges, TaintRanges srcTaintRanges) { int p1 = 0; int p2 = 0; int p3 = 0; @@ -90,14 +89,214 @@ public TaintRanges run(Object source, Object target, Object[]params, TaintRanges switch (this.command) { case KEEP: - this.builder.keep(tr, target, this.paramsCount, newTaintRanges); + this.builder.keep(tr, target, this.paramsCount, srcTaintRanges); break; case APPEND: - this.builder.append(tr, target, oldTaintRanges, source, newTaintRanges, p1, p2, this.paramsCount); + this.builder.append(tr, target, oldTaintRanges, source, srcTaintRanges, p1, p2, this.paramsCount); + break; + case SUBSET: + this.builder.subset(tr, oldTaintRanges, source, srcTaintRanges, p1, p2, p3, this.paramsCount); + break; default: break; } return tr; } + + public static TaintCommandRunner getCommandRunner(String signature) { + return RUNNER_MAP.get(signature); + } + + private static final Map RUNNER_MAP = new HashMap() {{ + // KEEP String + String METHOD = "java.lang.String.(java.lang.String)"; + put(METHOD, create(METHOD, TaintCommand.KEEP)); + METHOD = "java.lang.String.(java.lang.StringBuilder)"; + put(METHOD, create(METHOD, TaintCommand.KEEP)); + METHOD = "java.lang.String.(java.lang.StringBuffer)"; + put(METHOD, create(METHOD, TaintCommand.KEEP)); + METHOD = "java.lang.String.(byte[],int,int)"; + put(METHOD, create(METHOD, TaintCommand.KEEP)); + METHOD = "java.lang.String.(byte[],int,int,int)"; + put(METHOD, create(METHOD, TaintCommand.KEEP)); + METHOD = "java.lang.String.(byte[],int,int,java.lang.String)"; + put(METHOD, create(METHOD, TaintCommand.KEEP)); + METHOD = "java.lang.String.(char[])"; + put(METHOD, create(METHOD, TaintCommand.KEEP)); + METHOD = "java.lang.String.(byte[],java.nio.charset.Charset)"; // Java-11 + put(METHOD, create(METHOD, TaintCommand.KEEP)); + METHOD = "java.lang.String.(byte[],byte)"; // Java-17 + put(METHOD, create(METHOD, TaintCommand.KEEP)); + METHOD = "java.lang.String.toLowerCase(java.util.Locale)"; + put(METHOD, create(METHOD, TaintCommand.KEEP)); + METHOD = "java.lang.String.toUpperCase(java.util.Locale)"; + put(METHOD, create(METHOD, TaintCommand.KEEP)); + METHOD = "java.lang.String.getBytes()"; + put(METHOD, create(METHOD, TaintCommand.KEEP)); + METHOD = "java.lang.String.getBytes(java.lang.String)"; + put(METHOD, create(METHOD, TaintCommand.KEEP)); + METHOD = "java.lang.String.getBytes(java.nio.charset.Charset)"; + put(METHOD, create(METHOD, TaintCommand.KEEP)); + METHOD = "java.lang.String.toCharArray()"; + put(METHOD, create(METHOD, TaintCommand.KEEP)); + + // KEEP StringBuilder + METHOD = "java.lang.StringBuilder.toString()"; + put(METHOD, create(METHOD, TaintCommand.KEEP)); + METHOD = "java.lang.StringBuilder.(java.lang.String)"; + put(METHOD, create(METHOD, TaintCommand.KEEP)); + METHOD = "java.lang.StringBuilder.(java.lang.CharSequence)"; + put(METHOD, create(METHOD, TaintCommand.KEEP)); + + // KEEP StringBuffer + METHOD = "java.lang.StringBuffer.toString()"; + put(METHOD, create(METHOD, TaintCommand.KEEP)); + METHOD = "java.lang.StringBuffer.(java.lang.String)"; + put(METHOD, create(METHOD, TaintCommand.KEEP)); + METHOD = "java.lang.StringBuffer.(java.lang.CharSequence)"; + put(METHOD, create(METHOD, TaintCommand.KEEP)); + + // KEEP ByteArrayOutputStream + METHOD = "java.io.ByteArrayOutputStream.toByteArray()"; + put(METHOD, create(METHOD, TaintCommand.KEEP)); + METHOD = "java.io.ByteArrayOutputStream.toString()"; + put(METHOD, create(METHOD, TaintCommand.KEEP)); + METHOD = "java.io.ByteArrayOutputStream.toString(java.lang.String)"; + put(METHOD, create(METHOD, TaintCommand.KEEP)); + METHOD = "java.io.ByteArrayOutputStream.toString(int)"; + put(METHOD, create(METHOD, TaintCommand.KEEP)); + METHOD = "java.io.ByteArrayOutputStream.toString(java.nio.charset.Charset)"; + put(METHOD, create(METHOD, TaintCommand.KEEP)); + + // KEEP StringConcatHelper + METHOD = "java.lang.StringConcatHelper.newString(byte[],int,byte)"; // Java 9-11 + put(METHOD, create(METHOD, TaintCommand.KEEP)); + METHOD = "java.lang.StringConcatHelper.newString(byte[],long)"; // Java 12+, up to 14 + put(METHOD, create(METHOD, TaintCommand.KEEP)); + + // KEEP StringWriter + METHOD = "java.io.StringWriter.toString()"; + put(METHOD, create(METHOD, TaintCommand.KEEP)); + + // APPEND String + METHOD = "java.lang.String.(char[],int,int)"; + put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3", "0"))); + METHOD = "java.lang.String.(char[],int,int,boolean)"; // in IBM JDK8 split() + put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3", "0"))); + + // APPEND StringLatin1/StringUTF16 + METHOD = "java.lang.StringLatin1.newString(byte[],int,int)"; // Java-11 + put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3", "0"))); + METHOD = "java.lang.StringUTF16.newString(byte[],int,int)"; // Java-11 + put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3", "0"))); + + // APPEND StringBuilder + METHOD = "java.lang.StringBuilder.append(java.lang.String)"; + put(METHOD, create(METHOD, TaintCommand.APPEND)); + METHOD = "java.lang.StringBuilder.append(java.lang.StringBuffer)"; + put(METHOD, create(METHOD, TaintCommand.APPEND)); + METHOD = "java.lang.StringBuilder.append(java.lang.CharSequence)"; + put(METHOD, create(METHOD, TaintCommand.APPEND)); + METHOD = "java.lang.StringBuilder.append(java.lang.CharSequence,int,int)"; + put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3"))); + METHOD = "java.lang.StringBuilder.append(char[],int,int)"; + put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3", "0"))); + + // APPEND AbstractStringBuilder + METHOD = "java.lang.AbstractStringBuilder.append(java.lang.String)"; + put(METHOD, create(METHOD, TaintCommand.APPEND)); + + // APPEND StringBuffer + METHOD = "java.lang.StringBuffer.append(java.lang.String)"; + put(METHOD, create(METHOD, TaintCommand.APPEND)); + METHOD = "java.lang.StringBuffer.append(java.lang.StringBuffer)"; + put(METHOD, create(METHOD, TaintCommand.APPEND)); + METHOD = "java.lang.StringBuffer.append(char[])"; + put(METHOD, create(METHOD, TaintCommand.APPEND)); + METHOD = "java.lang.StringBuffer.append(java.lang.CharSequence)"; + put(METHOD, create(METHOD, TaintCommand.APPEND)); + METHOD = "java.lang.StringBuffer.append(java.lang.CharSequence,int,int)"; + put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3"))); + METHOD = "java.lang.StringBuffer.append(char[],int,int)"; + put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3", "0"))); + + // APPEND ByteArrayOutputStream + METHOD = "java.io.ByteArrayOutputStream.toString(java.nio.charset.Charset)"; + put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3"))); + + // APPEND StringWriter + METHOD = "java.io.StringWriter.write(char[],int,int)"; + put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3"))); + METHOD = "java.io.StringWriter.write(java.lang.String)"; + put(METHOD, create(METHOD, TaintCommand.APPEND)); + METHOD = "java.io.StringWriter.write(java.lang.String,int,int)"; + put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3"))); + + // APPEND apache ByteArrayOutputStream + METHOD = "org.apache.commons.io.output.ByteArrayOutputStream.write(byte[],int,int)"; + put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3"))); + + // SUBSET String + METHOD = "java.lang.String.substring(int)"; + put(METHOD, create(METHOD, TaintCommand.SUBSET, Collections.singletonList("P1"))); + METHOD = "java.lang.String.substring(int,int)"; + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P1", "P2"))); + METHOD = "java.lang.String.getBytes(int,int,byte[],int)"; + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P1", "P2", "P4"))); + METHOD = "java.lang.String.getChars(int,int,char[],int)"; + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P1", "P2", "P4"))); + METHOD = "java.lang.String.(byte[],int,int,java.nio.charset.Charset)"; + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P2", "P3"))); + + // SUBSET StringLatin1/StringUTF16 LinesSpliterator + METHOD = "java.lang.StringLatin1$LinesSpliterator.(byte[],int,int)"; // Java-11 + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P2", "P3"))); + METHOD = "java.lang.StringUTF16$LinesSpliterator.(byte[],int,int)"; // Java-11 + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P2", "P3"))); + + // SUBSET StringBuilder + METHOD = "java.lang.StringBuilder.substring(int)"; + put(METHOD, create(METHOD, TaintCommand.SUBSET, Collections.singletonList("P1"))); + METHOD = "java.lang.StringBuilder.substring(int,int)"; + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P1", "P2"))); + METHOD = "java.lang.StringBuilder.setLength(int)"; + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("0", "P1"))); + METHOD = "java.lang.StringBuilder.getChars(int,int,char[],int)"; + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P1", "P2", "P4"))); + + // SUBSET AbstractStringBuilder + METHOD = "java.lang.AbstractStringBuilder.substring(int)"; + put(METHOD, create(METHOD, TaintCommand.SUBSET, Collections.singletonList("P1"))); + METHOD = "java.lang.AbstractStringBuilder.substring(int,int)"; + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P1", "P2"))); + METHOD = "java.lang.AbstractStringBuilder.setLength(int)"; + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("0", "P1"))); + METHOD = "java.lang.AbstractStringBuilder.getChars(int,int,char[],int)"; + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P1", "P2", "P4"))); + + // SUBSET StringBuffer + METHOD = "java.lang.StringBuffer.substring(int)"; + put(METHOD, create(METHOD, TaintCommand.SUBSET, Collections.singletonList("P1"))); + METHOD = "java.lang.StringBuffer.substring(int,int)"; + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P1", "P2"))); + METHOD = "java.lang.StringBuffer.setLength(int)"; + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("0", "P1"))); + METHOD = "java.lang.StringBuffer.getChars(int,int,char[],int)"; + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P1", "P2", "P4"))); + + // SUBSET ByteBuffer + METHOD = "java.nio.ByteBuffer.wrap(byte[],int,int)"; + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P2", "P3"))); + + // SUBSET Arrays + METHOD = "java.util.Arrays.copyOf(byte[],int)"; + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("0", "P2"))); + METHOD = "java.util.Arrays.copyOfRange(byte[],int,int)"; + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P2", "P3"))); + METHOD = "java.util.Arrays.copyOf(char[],int)"; + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("0", "P2"))); + METHOD = "java.util.Arrays.copyOfRange(char[],int,int)"; + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P2", "P3"))); + }}; } diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesBuilder.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesBuilder.java index 60634b83f..980f078a4 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesBuilder.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesBuilder.java @@ -4,31 +4,18 @@ import java.io.StringWriter; public class TaintRangesBuilder { - public enum Command { - KEEP, - APPEND, - SUBSET, - INSERT, - REMOVE, - REPLACE, - CONCAT, - TRIM, - TRIM_RIGHT, - TRIM_LEFT, - } - - public void keep(TaintRanges taintRanges, Object target, int argC, TaintRanges newTaintRanges) { + public void keep(TaintRanges taintRanges, Object target, int argC, TaintRanges srcTaintRanges) { if (argC == 0) { - int length = this.getLength(target); + int length = getLength(target); if (length > 0) { - for (TaintRange taintRange : newTaintRanges.getTaintRanges()) { + for (TaintRange taintRange : srcTaintRanges.getTaintRanges()) { if (taintRange.getStart() < length && taintRange.getStop() > length) { taintRange.setStop(length); } taintRanges.add(taintRange); } } else { - taintRanges.addAll(newTaintRanges); + taintRanges.addAll(srcTaintRanges); } taintRanges.merge(); @@ -36,26 +23,26 @@ public void keep(TaintRanges taintRanges, Object target, int argC, TaintRanges n } public void append(TaintRanges taintRanges, Object target, TaintRanges oldTaintRanges, - Object source, TaintRanges newTaintRanges, int p1, int p2, int argC) { - int length = this.getLength(target); + Object source, TaintRanges srcTaintRanges, int p1, int p2, int argC) { + int length = getLength(target); switch (argC) { case 0: // src.append(tgt) - newTaintRanges.shift(length - this.getLength(source)); + srcTaintRanges.shift(length - getLength(source)); taintRanges.addAll(oldTaintRanges); - taintRanges.addAll(newTaintRanges); + taintRanges.addAll(srcTaintRanges); break; case 2: - newTaintRanges.trim(p1, p2); - newTaintRanges.shift(length - (p2 - p1)); + srcTaintRanges.trim(p1, p2); + srcTaintRanges.shift(length - (p2 - p1)); taintRanges.addAll(oldTaintRanges); - taintRanges.addAll(newTaintRanges); + taintRanges.addAll(srcTaintRanges); break; case 3: - newTaintRanges.trim(p1, p1 + p2); - newTaintRanges.shift(length - p2); + srcTaintRanges.trim(p1, p1 + p2); + srcTaintRanges.shift(length - p2); taintRanges.addAll(oldTaintRanges); - taintRanges.addAll(newTaintRanges); + taintRanges.addAll(srcTaintRanges); break; default: return; @@ -63,23 +50,23 @@ public void append(TaintRanges taintRanges, Object target, TaintRanges oldTaintR taintRanges.merge(); } - public void subset(TaintRanges taintRanges, TaintRanges oldTaintRanges, Object source, TaintRanges newTaintRanges, int p1, int p2, int p3, int argC) { - int length = this.getLength(source); + public void subset(TaintRanges taintRanges, TaintRanges oldTaintRanges, Object source, TaintRanges srcTaintRanges, int p1, int p2, int p3, int argC) { + int length = getLength(source); switch (argC) { case 1: - newTaintRanges.trim(p1, length); - taintRanges.addAll(newTaintRanges); + srcTaintRanges.trim(p1, length); + taintRanges.addAll(srcTaintRanges); break; case 2: - newTaintRanges.trim(p1, p2); - taintRanges.addAll(newTaintRanges); + srcTaintRanges.trim(p1, p2); + taintRanges.addAll(srcTaintRanges); break; case 3: oldTaintRanges.clear(p3, (p3 + p2) - p1); - newTaintRanges.trim(p1, p2); - newTaintRanges.shift(p3); + srcTaintRanges.trim(p1, p2); + srcTaintRanges.shift(p3); taintRanges.addAll(oldTaintRanges); - taintRanges.addAll(newTaintRanges); + taintRanges.addAll(srcTaintRanges); break; default: return; @@ -88,7 +75,7 @@ public void subset(TaintRanges taintRanges, TaintRanges oldTaintRanges, Object s } public void insert(TaintRanges taintRanges, TaintRanges srcTaintRanges, Object source, TaintRanges tgtTaintRanges, int p1, int p2, int p3, int argC) { - int length = this.getLength(source); + int length = getLength(source); switch (argC) { case 1: tgtTaintRanges.shift(p1); @@ -113,7 +100,7 @@ public void insert(TaintRanges taintRanges, TaintRanges srcTaintRanges, Object s public void remove(TaintRanges taintRanges, Object source, TaintRanges tgtTaintRanges, int p1, int p2, int argC) { switch (argC) { case 0: - tgtTaintRanges.remove(0, this.getLength(source)); + tgtTaintRanges.remove(0, getLength(source)); break; case 1: tgtTaintRanges.remove(p1, p1 + 1); @@ -131,19 +118,19 @@ public void remove(TaintRanges taintRanges, Object source, TaintRanges tgtTaintR public void replace(TaintRanges taintRanges, Object target, TaintRanges srcTaintRanges, TaintRanges tgtTaintRanges) { // @TODO - taintRanges.add(new TaintRange(0, this.getLength(target))); + taintRanges.add(new TaintRange(0, getLength(target))); } public void concat(TaintRanges taintRanges, Object target, TaintRanges srcTaintRanges, Object source, TaintRanges tgtTaintRanges, Object[] params) { if (params != null && params.length == 1 && source.equals(params[0])) { - tgtTaintRanges.shift(this.getLength(target) - this.getLength(source)); + tgtTaintRanges.shift(getLength(target) - getLength(source)); } taintRanges.addAll(srcTaintRanges); taintRanges.addAll(tgtTaintRanges); taintRanges.merge(); } - public void trim(Command command, TaintRanges taintRanges, Object source, TaintRanges tgtTaintRanges, int argC) { + public void trim(TaintCommand command, TaintRanges taintRanges, Object source, TaintRanges tgtTaintRanges, int argC) { if (argC > 0) { return; } @@ -155,12 +142,12 @@ public void trim(Command command, TaintRanges taintRanges, Object source, TaintR int left = 0; CharSequence charSequence = (CharSequence) source; int length = charSequence.length(); - if (command.equals(Command.TRIM) || command.equals(Command.TRIM_LEFT)) { + if (command.equals(TaintCommand.TRIM) || command.equals(TaintCommand.TRIM_LEFT)) { while (left < length && Character.isWhitespace(charSequence.charAt(left))) { left++; } } - if (command.equals(Command.TRIM) || command.equals(Command.TRIM_RIGHT)) { + if (command.equals(TaintCommand.TRIM) || command.equals(TaintCommand.TRIM_RIGHT)) { int right = length; while (right > 0 && Character.isWhitespace(charSequence.charAt(right - 1))) { right--; @@ -177,7 +164,7 @@ public void trim(Command command, TaintRanges taintRanges, Object source, TaintR } } - public String obj2String(Object obj) { + public static String obj2String(Object obj) { if (obj == null) { return ""; } @@ -199,7 +186,7 @@ public String obj2String(Object obj) { } } - public int getLength(Object obj) { + public static int getLength(Object obj) { if (obj == null) { return 0; } diff --git a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderTrimTest.java b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderTrimTest.java index 35a462404..d21e79009 100644 --- a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderTrimTest.java +++ b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderTrimTest.java @@ -16,7 +16,7 @@ public void testTrim() { ts = new TaintRanges(); tgtTs = new TaintRanges(new TaintRange(3, 7)); // " fOOBAr ".trim() // fOOBAr - tb.trim(TaintRangesBuilder.Command.TRIM, ts, " fOOBAr ", tgtTs, 0); + tb.trim(TaintCommand.Command.TRIM, ts, " fOOBAr ", tgtTs, 0); Assert.assertEquals("Taints:[untrusted(1,5)]", ts.toString()); } @@ -29,7 +29,7 @@ public void testTrimLeft() { ts = new TaintRanges(); tgtTs = new TaintRanges(new TaintRange(3, 7)); // " fOOBAr".trim() // fOOBAr - tb.trim(TaintRangesBuilder.Command.TRIM_LEFT, ts, " fOOBAr", tgtTs, 0); + tb.trim(TaintCommand.Command.TRIM_LEFT, ts, " fOOBAr", tgtTs, 0); Assert.assertEquals("Taints:[untrusted(1,5)]", ts.toString()); } @@ -42,7 +42,7 @@ public void testTrimRight() throws IOException { ts = new TaintRanges(); tgtTs = new TaintRanges(new TaintRange(1, 5)); // "fOOBAr ".trim() // fOOBAr - tb.trim(TaintRangesBuilder.Command.TRIM_RIGHT, ts, "fOOBAr ", tgtTs, 0); + tb.trim(TaintCommand.Command.TRIM_RIGHT, ts, "fOOBAr ", tgtTs, 0); Assert.assertEquals("Taints:[untrusted(1,5)]", ts.toString()); } } From c42f4c2392d7f0caf330ffde5092c5943c2dcbb7 Mon Sep 17 00:00:00 2001 From: lostsnow Date: Thu, 25 Aug 2022 15:58:36 +0800 Subject: [PATCH 10/19] taint range insert --- .../taintrange/TaintCommandRunner.java | 41 +++++++++++++ .../taintrange/TaintRangesBuilder.java | 45 +++++++------- .../TaintRangeBuilderAppendTest.java | 54 ++++++++--------- .../TaintRangeBuilderConcatTest.java | 8 +-- .../TaintRangeBuilderInsertTest.java | 52 ++++++++-------- .../taintrange/TaintRangeBuilderKeepTest.java | 21 +++---- .../TaintRangeBuilderRemoveTest.java | 24 ++++---- .../TaintRangeBuilderSubsetTest.java | 60 +++++++++---------- .../taintrange/TaintRangeBuilderTrimTest.java | 18 +++--- 9 files changed, 179 insertions(+), 144 deletions(-) diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommandRunner.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommandRunner.java index 0338e8136..dd0224da9 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommandRunner.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommandRunner.java @@ -97,6 +97,9 @@ public TaintRanges run(Object source, Object target, Object[] params, TaintRange case SUBSET: this.builder.subset(tr, oldTaintRanges, source, srcTaintRanges, p1, p2, p3, this.paramsCount); break; + case INSERT: + this.builder.insert(tr, oldTaintRanges, source, srcTaintRanges, p1, p2, p3, this.paramsCount); + break; default: break; } @@ -298,5 +301,43 @@ public static TaintCommandRunner getCommandRunner(String signature) { put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("0", "P2"))); METHOD = "java.util.Arrays.copyOfRange(char[],int,int)"; put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P2", "P3"))); + + // INSERT CharArrayReader/PipedReader/PipedInputStream + METHOD = "java.io.CharArrayReader.(char[],int,int)"; + put(METHOD, create(METHOD, TaintCommand.INSERT, Arrays.asList("0", "P2", "P3"))); + METHOD = "java.io.CharArrayReader.read(char[],int,int)"; + put(METHOD, create(METHOD, TaintCommand.INSERT, Arrays.asList("0", "P2", "P3"))); + METHOD = "java.io.PipedReader.read(char[],int,int)"; + put(METHOD, create(METHOD, TaintCommand.INSERT, Arrays.asList("0", "P2", "P3"))); + METHOD = "java.io.PipedInputStream.read(byte[],int,int)"; + put(METHOD, create(METHOD, TaintCommand.INSERT, Arrays.asList("0", "P2", "P3"))); + + // INSERT StringBuilder + METHOD = "java.lang.StringBuilder.insert(int,java.lang.String)"; + put(METHOD, create(METHOD, TaintCommand.INSERT, Collections.singletonList("P1"))); + METHOD = "java.lang.StringBuilder.insert(int,char[])"; + put(METHOD, create(METHOD, TaintCommand.INSERT, Collections.singletonList("P1"))); + METHOD = "java.lang.StringBuilder.insert(int,char)"; + put(METHOD, create(METHOD, TaintCommand.INSERT, Collections.singletonList("P1"))); + METHOD = "java.lang.StringBuilder.insert(int,java.lang.CharSequence)"; + put(METHOD, create(METHOD, TaintCommand.INSERT, Collections.singletonList("P1"))); + METHOD = "java.lang.StringBuilder.insert(int,java.lang.CharSequence,int,int)"; + put(METHOD, create(METHOD, TaintCommand.INSERT, Arrays.asList("P1", "P3", "P4"))); + METHOD = "java.lang.StringBuilder.insert(int,char[],int,int)"; + put(METHOD, create(METHOD, TaintCommand.INSERT, Arrays.asList("P1", "P3", "P4"))); + + // INSERT StringBuffer + METHOD = "java.lang.StringBuffer.insert(int,java.lang.String)"; + put(METHOD, create(METHOD, TaintCommand.INSERT, Collections.singletonList("P1"))); + METHOD = "java.lang.StringBuffer.insert(int,char[])"; + put(METHOD, create(METHOD, TaintCommand.INSERT, Collections.singletonList("P1"))); + METHOD = "java.lang.StringBuffer.insert(int,char)"; + put(METHOD, create(METHOD, TaintCommand.INSERT, Collections.singletonList("P1"))); + METHOD = "java.lang.StringBuffer.insert(int,java.lang.CharSequence)"; + put(METHOD, create(METHOD, TaintCommand.INSERT, Collections.singletonList("P1"))); + METHOD = "java.lang.StringBuffer.insert(int,java.lang.CharSequence,int,int)"; + put(METHOD, create(METHOD, TaintCommand.INSERT, Arrays.asList("P1", "P3", "P4"))); + METHOD = "java.lang.StringBuffer.insert(int,char[],int,int)"; + put(METHOD, create(METHOD, TaintCommand.INSERT, Arrays.asList("P1", "P3", "P4"))); }}; } diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesBuilder.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesBuilder.java index 980f078a4..4f8c5dac6 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesBuilder.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesBuilder.java @@ -27,7 +27,6 @@ public void append(TaintRanges taintRanges, Object target, TaintRanges oldTaintR int length = getLength(target); switch (argC) { case 0: - // src.append(tgt) srcTaintRanges.shift(length - getLength(source)); taintRanges.addAll(oldTaintRanges); taintRanges.addAll(srcTaintRanges); @@ -74,22 +73,22 @@ public void subset(TaintRanges taintRanges, TaintRanges oldTaintRanges, Object s taintRanges.merge(); } - public void insert(TaintRanges taintRanges, TaintRanges srcTaintRanges, Object source, TaintRanges tgtTaintRanges, int p1, int p2, int p3, int argC) { + public void insert(TaintRanges taintRanges, TaintRanges oldTaintRanges, Object source, TaintRanges srcTaintRanges, int p1, int p2, int p3, int argC) { int length = getLength(source); switch (argC) { case 1: - tgtTaintRanges.shift(p1); - srcTaintRanges.split(p1, length + p1); + srcTaintRanges.shift(p1); + oldTaintRanges.split(p1, length + p1); + taintRanges.addAll(oldTaintRanges); taintRanges.addAll(srcTaintRanges); - taintRanges.addAll(tgtTaintRanges); break; case 3: length = p3 - p2; - tgtTaintRanges.subRange(p2, p3); - tgtTaintRanges.shift(p1 - p2); - srcTaintRanges.split(p1, length + p1); + srcTaintRanges.subRange(p2, p3); + srcTaintRanges.shift(p1 - p2); + oldTaintRanges.split(p1, length + p1); + taintRanges.addAll(oldTaintRanges); taintRanges.addAll(srcTaintRanges); - taintRanges.addAll(tgtTaintRanges); break; default: return; @@ -97,18 +96,18 @@ public void insert(TaintRanges taintRanges, TaintRanges srcTaintRanges, Object s taintRanges.merge(); } - public void remove(TaintRanges taintRanges, Object source, TaintRanges tgtTaintRanges, int p1, int p2, int argC) { + public void remove(TaintRanges taintRanges, Object source, TaintRanges srcTaintRanges, int p1, int p2, int argC) { switch (argC) { case 0: - tgtTaintRanges.remove(0, getLength(source)); + srcTaintRanges.remove(0, getLength(source)); break; case 1: - tgtTaintRanges.remove(p1, p1 + 1); - taintRanges.addAll(tgtTaintRanges); + srcTaintRanges.remove(p1, p1 + 1); + taintRanges.addAll(srcTaintRanges); break; case 2: - tgtTaintRanges.remove(p1, p2); - taintRanges.addAll(tgtTaintRanges); + srcTaintRanges.remove(p1, p2); + taintRanges.addAll(srcTaintRanges); break; default: return; @@ -116,27 +115,27 @@ public void remove(TaintRanges taintRanges, Object source, TaintRanges tgtTaintR taintRanges.merge(); } - public void replace(TaintRanges taintRanges, Object target, TaintRanges srcTaintRanges, TaintRanges tgtTaintRanges) { + public void replace(TaintRanges taintRanges, Object target, TaintRanges oldTaintRanges, TaintRanges srcTaintRanges) { // @TODO taintRanges.add(new TaintRange(0, getLength(target))); } - public void concat(TaintRanges taintRanges, Object target, TaintRanges srcTaintRanges, Object source, TaintRanges tgtTaintRanges, Object[] params) { + public void concat(TaintRanges taintRanges, Object target, TaintRanges oldTaintRanges, Object source, TaintRanges srcTaintRanges, Object[] params) { if (params != null && params.length == 1 && source.equals(params[0])) { - tgtTaintRanges.shift(getLength(target) - getLength(source)); + srcTaintRanges.shift(getLength(target) - getLength(source)); } + taintRanges.addAll(oldTaintRanges); taintRanges.addAll(srcTaintRanges); - taintRanges.addAll(tgtTaintRanges); taintRanges.merge(); } - public void trim(TaintCommand command, TaintRanges taintRanges, Object source, TaintRanges tgtTaintRanges, int argC) { + public void trim(TaintCommand command, TaintRanges taintRanges, Object source, TaintRanges srcTaintRanges, int argC) { if (argC > 0) { return; } - if (!tgtTaintRanges.isEmpty()) { + if (!srcTaintRanges.isEmpty()) { if (!(source instanceof CharSequence)) { - taintRanges.addAll(tgtTaintRanges.getTaintRanges()); + taintRanges.addAll(srcTaintRanges.getTaintRanges()); return; } int left = 0; @@ -154,7 +153,7 @@ public void trim(TaintCommand command, TaintRanges taintRanges, Object source, T } length = right; } - for (TaintRange taintRange : tgtTaintRanges.getTaintRanges()) { + for (TaintRange taintRange : srcTaintRanges.getTaintRanges()) { int max = Math.max(0, taintRange.getStart() - left); int min = Math.min(length, taintRange.getStop()) - left; if (min > max) { diff --git a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderAppendTest.java b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderAppendTest.java index 9002b760a..27690ae01 100644 --- a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderAppendTest.java +++ b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderAppendTest.java @@ -7,80 +7,80 @@ public class TaintRangeBuilderAppendTest { @Test public void testAppend() { TaintRanges ts; + TaintRanges oldTs; TaintRanges srcTs; - TaintRanges tgtTs; TaintRangesBuilder tb = new TaintRangesBuilder(); ts = new TaintRanges(); - srcTs = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(0, 3)); + oldTs = new TaintRanges(); + srcTs = new TaintRanges(new TaintRange(0, 3)); // "" + "FOO" - tb.append(ts, new StringBuilder("FOO"), srcTs, "FOO", tgtTs, 0, 0, 0); + tb.append(ts, new StringBuilder("FOO"), oldTs, "FOO", srcTs, 0, 0, 0); Assert.assertEquals("Taints:[untrusted(0,3)]", ts.toString()); ts = new TaintRanges(); - srcTs = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(0, 3)); + oldTs = new TaintRanges(); + srcTs = new TaintRanges(new TaintRange(0, 3)); // "foo" + "bar" - tb.append(ts, new StringBuilder("fooBAR"), srcTs, "BAR", tgtTs, 0, 0, 0); + tb.append(ts, new StringBuilder("fooBAR"), oldTs, "BAR", srcTs, 0, 0, 0); Assert.assertEquals("Taints:[untrusted(3,6)]", ts.toString()); ts = new TaintRanges(); - srcTs = new TaintRanges(new TaintRange(0, 1)); - tgtTs = new TaintRanges(new TaintRange(1, 2)); + oldTs = new TaintRanges(new TaintRange(0, 1)); + srcTs = new TaintRanges(new TaintRange(1, 2)); // "Foo" + "bAr" - tb.append(ts, new StringBuilder("FoobAr"), srcTs, "bAr", tgtTs, 0, 0, 0); + tb.append(ts, new StringBuilder("FoobAr"), oldTs, "bAr", srcTs, 0, 0, 0); Assert.assertEquals("Taints:[untrusted(0,1), untrusted(4,5)]", ts.toString()); } @Test public void testAppendStartStop() { TaintRanges ts; + TaintRanges oldTs; TaintRanges srcTs; - TaintRanges tgtTs; TaintRangesBuilder tb = new TaintRangesBuilder(); ts = new TaintRanges(); - srcTs = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(0, 5)); + oldTs = new TaintRanges(); + srcTs = new TaintRanges(new TaintRange(0, 5)); // StringBuilder("foo").append("ZBARZ", 1, 4) - tb.append(ts, new StringBuilder("fooBAR"), srcTs, "ZBARZ", tgtTs, 1, 4, 2); + tb.append(ts, new StringBuilder("fooBAR"), oldTs, "ZBARZ", srcTs, 1, 4, 2); Assert.assertEquals("Taints:[untrusted(3,6)]", ts.toString()); ts = new TaintRanges(); - srcTs = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(0, 3)); + oldTs = new TaintRanges(); + srcTs = new TaintRanges(new TaintRange(0, 3)); // StringBuilder("foo").append("ZBArz", 1, 4) - tb.append(ts, new StringBuilder("fooBAr"), srcTs, "ZBArz", tgtTs, 1, 4, 2); + tb.append(ts, new StringBuilder("fooBAr"), oldTs, "ZBArz", srcTs, 1, 4, 2); Assert.assertEquals("Taints:[untrusted(3,5)]", ts.toString()); } @Test public void testAppendStartLength() { TaintRanges ts; + TaintRanges oldTs; TaintRanges srcTs; - TaintRanges tgtTs; TaintRangesBuilder tb = new TaintRangesBuilder(); ts = new TaintRanges(); - srcTs = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(0, 5)); + oldTs = new TaintRanges(); + srcTs = new TaintRanges(new TaintRange(0, 5)); // StringBuilder("foo").append(char[]{"ZBARZ"}, 1, 3) - tb.append(ts, new StringBuilder("fooBAR"), srcTs, "ZBARZ", tgtTs, 1, 3, 3); + tb.append(ts, new StringBuilder("fooBAR"), oldTs, "ZBARZ", srcTs, 1, 3, 3); Assert.assertEquals("Taints:[untrusted(3,6)]", ts.toString()); ts = new TaintRanges(); - srcTs = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(0, 2)); + oldTs = new TaintRanges(); + srcTs = new TaintRanges(new TaintRange(0, 2)); // StringBuilder("foo").append(char[]{"ZBarz"}, 1, 3) - tb.append(ts, new StringBuilder("fooBar"), srcTs, "ZBarz", tgtTs, 1, 3, 3); + tb.append(ts, new StringBuilder("fooBar"), oldTs, "ZBarz", srcTs, 1, 3, 3); Assert.assertEquals("Taints:[untrusted(3,4)]", ts.toString()); ts = new TaintRanges(); - srcTs = new TaintRanges(new TaintRange(2, 3)); - tgtTs = new TaintRanges(new TaintRange(0, 2)); + oldTs = new TaintRanges(new TaintRange(2, 3)); + srcTs = new TaintRanges(new TaintRange(0, 2)); // StringBuilder("foO").append(char[]{"ZBarz"}, 1, 3) - tb.append(ts, new StringBuilder("foOBar"), srcTs, "ZBarz", tgtTs, 1, 3, 3); + tb.append(ts, new StringBuilder("foOBar"), oldTs, "ZBarz", srcTs, 1, 3, 3); Assert.assertEquals("Taints:[untrusted(2,4)]", ts.toString()); } } diff --git a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderConcatTest.java b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderConcatTest.java index f5e34f70a..ff25ae8a3 100644 --- a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderConcatTest.java +++ b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderConcatTest.java @@ -9,15 +9,15 @@ public class TaintRangeBuilderConcatTest { @Test public void testConcat() throws IOException { TaintRanges ts; + TaintRanges oldTs; TaintRanges srcTs; - TaintRanges tgtTs; TaintRangesBuilder tb = new TaintRangesBuilder(); ts = new TaintRanges(); - srcTs = new TaintRanges(new TaintRange(1, 3)); - tgtTs = new TaintRanges(new TaintRange(0, 2)); + oldTs = new TaintRanges(new TaintRange(1, 3)); + srcTs = new TaintRanges(new TaintRange(0, 2)); // "fOO".concat("BAr") // fOOBAr - tb.concat(ts, "fOOBAr", srcTs, "BAr", tgtTs, new String[]{"BAr"}); + tb.concat(ts, "fOOBAr", oldTs, "BAr", srcTs, new String[]{"BAr"}); Assert.assertEquals("Taints:[untrusted(1,5)]", ts.toString()); } } diff --git a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderInsertTest.java b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderInsertTest.java index 4eb82f82a..77e306d53 100644 --- a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderInsertTest.java +++ b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderInsertTest.java @@ -7,72 +7,72 @@ public class TaintRangeBuilderInsertTest { @Test public void testInsert() { TaintRanges ts; + TaintRanges oldTs; TaintRanges srcTs; - TaintRanges tgtTs; TaintRangesBuilder tb = new TaintRangesBuilder(); ts = new TaintRanges(); - srcTs = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(0,2)); + oldTs = new TaintRanges(); + srcTs = new TaintRanges(new TaintRange(0, 2)); // new StringBuilder("fbar").insert(1, "OO") // fOObar - tb.insert(ts, srcTs, new StringBuilder("OO"), tgtTs, 1, 0, 0, 1); + tb.insert(ts, oldTs, new StringBuilder("OO"), srcTs, 1, 0, 0, 1); Assert.assertEquals("Taints:[untrusted(1,3)]", ts.toString()); ts = new TaintRanges(); - srcTs = new TaintRanges(new TaintRange(2,3)); - tgtTs = new TaintRanges(new TaintRange(0,2)); + oldTs = new TaintRanges(new TaintRange(2, 3)); + srcTs = new TaintRanges(new TaintRange(0, 2)); // new StringBuilder("fbAr").insert(1, "OO") // fOObAr - tb.insert(ts, srcTs, new StringBuilder("OO"), tgtTs, 1, 0, 0, 1); + tb.insert(ts, oldTs, new StringBuilder("OO"), srcTs, 1, 0, 0, 1); Assert.assertEquals("Taints:[untrusted(4,5), untrusted(1,3)]", ts.toString()); ts = new TaintRanges(); - srcTs = new TaintRanges(new TaintRange(0,1), new TaintRange(2,3)); - tgtTs = new TaintRanges(new TaintRange(1,2)); + oldTs = new TaintRanges(new TaintRange(0, 1), new TaintRange(2, 3)); + srcTs = new TaintRanges(new TaintRange(1, 2)); // new StringBuilder("FbAr").insert(1, "oO") // FoObAr - tb.insert(ts, srcTs, new StringBuilder("oO"), tgtTs, 1, 0, 0, 1); + tb.insert(ts, oldTs, new StringBuilder("oO"), srcTs, 1, 0, 0, 1); Assert.assertEquals("Taints:[untrusted(0,1), untrusted(4,5), untrusted(2,3)]", ts.toString()); } @Test public void testInsertRange() { TaintRanges ts; + TaintRanges oldTs; TaintRanges srcTs; - TaintRanges tgtTs; TaintRangesBuilder tb = new TaintRangesBuilder(); ts = new TaintRanges(); - srcTs = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(2,4)); + oldTs = new TaintRanges(); + srcTs = new TaintRanges(new TaintRange(2, 4)); // new StringBuilder("foar").insert(2, "zzOBzz", 2, 4) // foOBar - tb.insert(ts, srcTs, new StringBuilder("zzOBzz"), tgtTs, 2, 2, 4, 3); + tb.insert(ts, oldTs, new StringBuilder("zzOBzz"), srcTs, 2, 2, 4, 3); Assert.assertEquals("Taints:[untrusted(2,4)]", ts.toString()); ts = new TaintRanges(); - srcTs = new TaintRanges(new TaintRange(0,1)); - tgtTs = new TaintRanges(new TaintRange(2,4)); + oldTs = new TaintRanges(new TaintRange(0, 1)); + srcTs = new TaintRanges(new TaintRange(2, 4)); // new StringBuilder("Foar").insert(2, "zzOBzz", 2, 4) // FoOBar - tb.insert(ts, srcTs, new StringBuilder("zzOBzz"), tgtTs, 2, 2, 4, 3); + tb.insert(ts, oldTs, new StringBuilder("zzOBzz"), srcTs, 2, 2, 4, 3); Assert.assertEquals("Taints:[untrusted(0,1), untrusted(2,4)]", ts.toString()); ts = new TaintRanges(); - srcTs = new TaintRanges(new TaintRange(3,4)); - tgtTs = new TaintRanges(new TaintRange(2,4)); + oldTs = new TaintRanges(new TaintRange(3, 4)); + srcTs = new TaintRanges(new TaintRange(2, 4)); // new StringBuilder("foaR").insert(2, "zzOBzz", 2, 4) // foOBaR - tb.insert(ts, srcTs, new StringBuilder("zzOBzz"), tgtTs, 2, 2, 4, 3); + tb.insert(ts, oldTs, new StringBuilder("zzOBzz"), srcTs, 2, 2, 4, 3); Assert.assertEquals("Taints:[untrusted(5,6), untrusted(2,4)]", ts.toString()); ts = new TaintRanges(); - srcTs = new TaintRanges(new TaintRange(2,3)); - tgtTs = new TaintRanges(new TaintRange(2,4)); + oldTs = new TaintRanges(new TaintRange(2, 3)); + srcTs = new TaintRanges(new TaintRange(2, 4)); // new StringBuilder("foAr").insert(2, "zzOBzz", 2, 4) // foOBAr - tb.insert(ts, srcTs, new StringBuilder("zzOBzz"), tgtTs, 2, 2, 4, 3); + tb.insert(ts, oldTs, new StringBuilder("zzOBzz"), srcTs, 2, 2, 4, 3); Assert.assertEquals("Taints:[untrusted(2,5)]", ts.toString()); ts = new TaintRanges(); - srcTs = new TaintRanges(new TaintRange(1,3)); - tgtTs = new TaintRanges(new TaintRange(3,4)); + oldTs = new TaintRanges(new TaintRange(1, 3)); + srcTs = new TaintRanges(new TaintRange(3, 4)); // new StringBuilder("fOAr").insert(2, "zzoBzz", 2, 4) // fOoBAr - tb.insert(ts, srcTs, new StringBuilder("zzoBzz"), tgtTs, 2, 2, 4, 3); + tb.insert(ts, oldTs, new StringBuilder("zzoBzz"), srcTs, 2, 2, 4, 3); Assert.assertEquals("Taints:[untrusted(1,2), untrusted(3,5)]", ts.toString()); } } diff --git a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderKeepTest.java b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderKeepTest.java index 82dcce925..0aed333c5 100644 --- a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderKeepTest.java +++ b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderKeepTest.java @@ -8,35 +8,30 @@ public class TaintRangeBuilderKeepTest { public void testKeep() { TaintRanges ts; TaintRanges srcTs; - TaintRanges tgtTs; TaintRangesBuilder tb = new TaintRangesBuilder(); ts = new TaintRanges(); - srcTs = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(0, 6)); + srcTs = new TaintRanges(new TaintRange(0, 6)); // new StringBuilder("FOOBAR") - tb.keep(ts, new StringBuilder("FOOBAR"), 0, tgtTs); + tb.keep(ts, new StringBuilder("FOOBAR"), 0, srcTs); Assert.assertEquals("Taints:[untrusted(0,6)]", ts.toString()); ts = new TaintRanges(); - srcTs = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(3, 5)); + srcTs = new TaintRanges(new TaintRange(3, 5)); // new StringBuilder("fooBAr") - tb.keep(ts, new StringBuilder("fooBAr"), 0, tgtTs); + tb.keep(ts, new StringBuilder("fooBAr"), 0, srcTs); Assert.assertEquals("Taints:[untrusted(3,5)]", ts.toString()); ts = new TaintRanges(); - srcTs = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(0, 1), new TaintRange(3, 5)); + srcTs = new TaintRanges(new TaintRange(0, 1), new TaintRange(3, 5)); // new StringBuilder("FooBAr") - tb.keep(ts, new StringBuilder("FooBAr"), 0, tgtTs); + tb.keep(ts, new StringBuilder("FooBAr"), 0, srcTs); Assert.assertEquals("Taints:[untrusted(0,1), untrusted(3,5)]", ts.toString()); ts = new TaintRanges(); - srcTs = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(1, 3), new TaintRange(3, 5)); + srcTs = new TaintRanges(new TaintRange(1, 3), new TaintRange(3, 5)); // new StringBuilder("fOOBAr") - tb.keep(ts, new StringBuilder("fOOBAr"), 0, tgtTs); + tb.keep(ts, new StringBuilder("fOOBAr"), 0, srcTs); Assert.assertEquals("Taints:[untrusted(1,5)]", ts.toString()); } } diff --git a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderRemoveTest.java b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderRemoveTest.java index 98166ccd8..7a6148a10 100644 --- a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderRemoveTest.java +++ b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderRemoveTest.java @@ -10,49 +10,49 @@ public class TaintRangeBuilderRemoveTest { @Test public void testRemoveReset() throws IOException { TaintRanges ts; - TaintRanges tgtTs; + TaintRanges srcTs; TaintRangesBuilder tb = new TaintRangesBuilder(); ByteArrayOutputStream baos; ts = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(0, 6)); + srcTs = new TaintRanges(new TaintRange(0, 6)); // new ByteArrayOutputStream(6).write("FOOBAR".getBytes()).reset() baos = new ByteArrayOutputStream(6); baos.write("FOOBAR".getBytes()); - tb.remove(ts, baos, tgtTs, 0, 0, 0); + tb.remove(ts, baos, srcTs, 0, 0, 0); Assert.assertEquals("Taints:[]", ts.toString()); ts = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(3, 6)); + srcTs = new TaintRanges(new TaintRange(3, 6)); // new ByteArrayOutputStream(6).write("fooBAR".getBytes()).reset() baos = new ByteArrayOutputStream(6); baos.write("fooBAR".getBytes()); - tb.remove(ts, baos, tgtTs, 0, 0, 0); + tb.remove(ts, baos, srcTs, 0, 0, 0); Assert.assertEquals("Taints:[]", ts.toString()); } @Test public void testRemoveCharAt() { TaintRanges ts; - TaintRanges tgtTs; + TaintRanges srcTs; TaintRangesBuilder tb = new TaintRangesBuilder(); ts = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(0, 7)); + srcTs = new TaintRanges(new TaintRange(0, 7)); // new StringBuilder("FOOZBAR").deleteCharAt(3) // FOOBAR - tb.remove(ts, new StringBuilder("FOOBAR"), tgtTs, 3, 0, 1); + tb.remove(ts, new StringBuilder("FOOBAR"), srcTs, 3, 0, 1); Assert.assertEquals("Taints:[untrusted(0,6)]", ts.toString()); ts = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(1, 6)); + srcTs = new TaintRanges(new TaintRange(1, 6)); // new StringBuilder("fOOZBAr").deleteCharAt(3) // fOOBAr - tb.remove(ts, new StringBuilder("fOOBAr"), tgtTs, 3, 0, 1); + tb.remove(ts, new StringBuilder("fOOBAr"), srcTs, 3, 0, 1); Assert.assertEquals("Taints:[untrusted(1,5)]", ts.toString()); ts = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(0, 3), new TaintRange(4, 7)); + srcTs = new TaintRanges(new TaintRange(0, 3), new TaintRange(4, 7)); // new StringBuilder("FOOzBAR").deleteCharAt(3) // FOOBAR - tb.remove(ts, new StringBuilder("FOOBAR"), tgtTs, 3, 0, 1); + tb.remove(ts, new StringBuilder("FOOBAR"), srcTs, 3, 0, 1); Assert.assertEquals("Taints:[untrusted(0,6)]", ts.toString()); } diff --git a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderSubsetTest.java b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderSubsetTest.java index 44d34276c..3d7e7a7d3 100644 --- a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderSubsetTest.java +++ b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderSubsetTest.java @@ -7,89 +7,89 @@ public class TaintRangeBuilderSubsetTest { @Test public void testSubsetStart() { TaintRanges ts; + TaintRanges oldTs; TaintRanges srcTs; - TaintRanges tgtTs; TaintRangesBuilder tb = new TaintRangesBuilder(); ts = new TaintRanges(); - srcTs = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(3, 6)); + oldTs = new TaintRanges(); + srcTs = new TaintRanges(new TaintRange(3, 6)); // new StringBuilder("fooBAR").substring(3) // BAR - tb.subset(ts, srcTs, new StringBuilder("fooBAR"), tgtTs, 3, 0, 0, 1); + tb.subset(ts, oldTs, new StringBuilder("fooBAR"), srcTs, 3, 0, 0, 1); Assert.assertEquals("Taints:[untrusted(0,3)]", ts.toString()); ts = new TaintRanges(); - srcTs = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(3, 6)); + oldTs = new TaintRanges(); + srcTs = new TaintRanges(new TaintRange(3, 6)); // new StringBuilder("fooBAR").substring(2) // oBAR - tb.subset(ts, srcTs, new StringBuilder("fooBAR"), tgtTs, 2, 0, 0, 1); + tb.subset(ts, oldTs, new StringBuilder("fooBAR"), srcTs, 2, 0, 0, 1); Assert.assertEquals("Taints:[untrusted(1,4)]", ts.toString()); ts = new TaintRanges(); - srcTs = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(3, 5)); + oldTs = new TaintRanges(); + srcTs = new TaintRanges(new TaintRange(3, 5)); // new StringBuilder("fooBAr").substring(4) // Ar - tb.subset(ts, srcTs, new StringBuilder("fooBAr"), tgtTs, 4, 0, 0, 1); + tb.subset(ts, oldTs, new StringBuilder("fooBAr"), srcTs, 4, 0, 0, 1); Assert.assertEquals("Taints:[untrusted(0,1)]", ts.toString()); } @Test public void testSubsetStartStop() { TaintRanges ts; + TaintRanges oldTs; TaintRanges srcTs; - TaintRanges tgtTs; TaintRangesBuilder tb = new TaintRangesBuilder(); ts = new TaintRanges(); - srcTs = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(3,6)); + oldTs = new TaintRanges(); + srcTs = new TaintRanges(new TaintRange(3, 6)); // new StringBuilder("fooBARbaz").substring(3, 6) // BAR - tb.subset(ts, srcTs, new StringBuilder("foobarbaz"), tgtTs, 3, 6, 0, 2); + tb.subset(ts, oldTs, new StringBuilder("foobarbaz"), srcTs, 3, 6, 0, 2); Assert.assertEquals("Taints:[untrusted(0,3)]", ts.toString()); ts = new TaintRanges(); - srcTs = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(3,6)); + oldTs = new TaintRanges(); + srcTs = new TaintRanges(new TaintRange(3, 6)); // new StringBuilder("fooBARbaz").substring(2, 5) // oBA - tb.subset(ts, srcTs, new StringBuilder("foobarbaz"), tgtTs, 2, 5, 0, 2); + tb.subset(ts, oldTs, new StringBuilder("foobarbaz"), srcTs, 2, 5, 0, 2); Assert.assertEquals("Taints:[untrusted(1,3)]", ts.toString()); ts = new TaintRanges(); - srcTs = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(3,5)); + oldTs = new TaintRanges(); + srcTs = new TaintRanges(new TaintRange(3, 5)); // new StringBuilder("fooBArbaz").substring(4, 7) // Arb - tb.subset(ts, srcTs, new StringBuilder("foobarbaz"), tgtTs, 4, 7, 0, 2); + tb.subset(ts, oldTs, new StringBuilder("foobarbaz"), srcTs, 4, 7, 0, 2); Assert.assertEquals("Taints:[untrusted(0,1)]", ts.toString()); } @Test public void testSubsetGetChars() { TaintRanges ts; + TaintRanges oldTs; TaintRanges srcTs; - TaintRanges tgtTs; TaintRangesBuilder tb = new TaintRangesBuilder(); ts = new TaintRanges(); - srcTs = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(1, 3)); + oldTs = new TaintRanges(); + srcTs = new TaintRanges(new TaintRange(1, 3)); // new StringBuilder("fOO").getChars(0, 3, chars, 0) // fOO - tb.subset(ts, srcTs, new StringBuilder("foo"), tgtTs, 0, 3, 0, 3); + tb.subset(ts, oldTs, new StringBuilder("foo"), srcTs, 0, 3, 0, 3); Assert.assertEquals("Taints:[untrusted(1,3)]", ts.toString()); ts = new TaintRanges(); - srcTs = new TaintRanges(new TaintRange(1, 3)); - tgtTs = new TaintRanges(new TaintRange(2, 5)); + oldTs = new TaintRanges(new TaintRange(1, 3)); + srcTs = new TaintRanges(new TaintRange(2, 5)); // chars: "fOO" // new StringBuilder("zzBARzz").getChars(2, 5, chars, 3) // fOOBAR - tb.subset(ts, srcTs, new StringBuilder("foo"), tgtTs, 2, 5, 3, 3); + tb.subset(ts, oldTs, new StringBuilder("foo"), srcTs, 2, 5, 3, 3); Assert.assertEquals("Taints:[untrusted(1,6)]", ts.toString()); ts = new TaintRanges(); - srcTs = new TaintRanges(new TaintRange(1, 2)); - tgtTs = new TaintRanges(new TaintRange(2, 5)); + oldTs = new TaintRanges(new TaintRange(1, 2)); + srcTs = new TaintRanges(new TaintRange(2, 5)); // chars: "fOo" // new StringBuilder("zzBARzz").getChars(2, 5, chars, 3) // fOoBAR - tb.subset(ts, srcTs, new StringBuilder("foo"), tgtTs, 2, 5, 3, 3); + tb.subset(ts, oldTs, new StringBuilder("foo"), srcTs, 2, 5, 3, 3); Assert.assertEquals("Taints:[untrusted(1,2), untrusted(3,6)]", ts.toString()); } } diff --git a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderTrimTest.java b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderTrimTest.java index d21e79009..36bd8b4fd 100644 --- a/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderTrimTest.java +++ b/dongtai-core/src/test/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangeBuilderTrimTest.java @@ -10,39 +10,39 @@ public class TaintRangeBuilderTrimTest { public void testTrim() { TaintRanges ts; - TaintRanges tgtTs; + TaintRanges srcTs; TaintRangesBuilder tb = new TaintRangesBuilder(); ts = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(3, 7)); + srcTs = new TaintRanges(new TaintRange(3, 7)); // " fOOBAr ".trim() // fOOBAr - tb.trim(TaintCommand.Command.TRIM, ts, " fOOBAr ", tgtTs, 0); + tb.trim(TaintCommand.TRIM, ts, " fOOBAr ", srcTs, 0); Assert.assertEquals("Taints:[untrusted(1,5)]", ts.toString()); } @Test public void testTrimLeft() { TaintRanges ts; - TaintRanges tgtTs; + TaintRanges srcTs; TaintRangesBuilder tb = new TaintRangesBuilder(); ts = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(3, 7)); + srcTs = new TaintRanges(new TaintRange(3, 7)); // " fOOBAr".trim() // fOOBAr - tb.trim(TaintCommand.Command.TRIM_LEFT, ts, " fOOBAr", tgtTs, 0); + tb.trim(TaintCommand.TRIM_LEFT, ts, " fOOBAr", srcTs, 0); Assert.assertEquals("Taints:[untrusted(1,5)]", ts.toString()); } @Test public void testTrimRight() throws IOException { TaintRanges ts; - TaintRanges tgtTs; + TaintRanges srcTs; TaintRangesBuilder tb = new TaintRangesBuilder(); ts = new TaintRanges(); - tgtTs = new TaintRanges(new TaintRange(1, 5)); + srcTs = new TaintRanges(new TaintRange(1, 5)); // "fOOBAr ".trim() // fOOBAr - tb.trim(TaintCommand.Command.TRIM_RIGHT, ts, "fOOBAr ", tgtTs, 0); + tb.trim(TaintCommand.TRIM_RIGHT, ts, "fOOBAr ", srcTs, 0); Assert.assertEquals("Taints:[untrusted(1,5)]", ts.toString()); } } From d712abb2469c741c6e25d3a4e991cccdd5f429bd Mon Sep 17 00:00:00 2001 From: lostsnow Date: Thu, 25 Aug 2022 16:23:21 +0800 Subject: [PATCH 11/19] taint range remove/concat/trim --- .../taintrange/TaintCommandRunner.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommandRunner.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommandRunner.java index dd0224da9..92a8dcc9f 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommandRunner.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommandRunner.java @@ -100,6 +100,17 @@ public TaintRanges run(Object source, Object target, Object[] params, TaintRange case INSERT: this.builder.insert(tr, oldTaintRanges, source, srcTaintRanges, p1, p2, p3, this.paramsCount); break; + case REMOVE: + this.builder.remove(tr, source, srcTaintRanges, p1, p2, this.paramsCount); + break; + case CONCAT: + this.builder.concat(tr, target, oldTaintRanges, source, srcTaintRanges, params); + break; + case TRIM: + case TRIM_LEFT: + case TRIM_RIGHT: + this.builder.trim(this.command, tr, source, srcTaintRanges, this.paramsCount); + break; default: break; } @@ -339,5 +350,37 @@ public static TaintCommandRunner getCommandRunner(String signature) { put(METHOD, create(METHOD, TaintCommand.INSERT, Arrays.asList("P1", "P3", "P4"))); METHOD = "java.lang.StringBuffer.insert(int,char[],int,int)"; put(METHOD, create(METHOD, TaintCommand.INSERT, Arrays.asList("P1", "P3", "P4"))); + + // REMOVE StringBuilder + METHOD = "java.lang.StringBuilder.delete(int,int)"; + put(METHOD, create(METHOD, TaintCommand.REMOVE, Arrays.asList("P1", "P2"))); + METHOD = "java.io.StringBuilder.deleteCharAt(int)"; + put(METHOD, create(METHOD, TaintCommand.REMOVE, Collections.singletonList("P1"))); + + // REMOVE StringBuffer + METHOD = "java.lang.StringBuffer.delete(int,int)"; + put(METHOD, create(METHOD, TaintCommand.REMOVE, Arrays.asList("P1", "P2"))); + METHOD = "java.io.StringBuffer.deleteCharAt(int)"; + put(METHOD, create(METHOD, TaintCommand.REMOVE, Collections.singletonList("P1"))); + + // REMOVE ByteArrayOutputStream/apache ByteArrayOutputStream + METHOD = "java.io.ByteArrayOutputStream.reset()"; + put(METHOD, create(METHOD, TaintCommand.REMOVE)); + METHOD = "org.apache.commons.io.output.ByteArrayOutputStream.reset()"; + put(METHOD, create(METHOD, TaintCommand.REMOVE)); + + // CONCAT String + METHOD = "java.lang.String.concat(java.lang.String)"; + put(METHOD, create(METHOD, TaintCommand.CONCAT)); + + // TRIM String + METHOD = "java.lang.String.strip()"; + put(METHOD, create(METHOD, TaintCommand.TRIM)); + METHOD = "java.lang.String.stripLeading()"; + put(METHOD, create(METHOD, TaintCommand.TRIM_LEFT)); + METHOD = "java.lang.String.stripTrailing()"; + put(METHOD, create(METHOD, TaintCommand.TRIM_RIGHT)); + METHOD = "java.lang.String.trim()"; + put(METHOD, create(METHOD, TaintCommand.TRIM)); }}; } From 8c92ecc925d606168e269bccb11ac63095cb0272 Mon Sep 17 00:00:00 2001 From: lostsnow Date: Fri, 26 Aug 2022 17:14:13 +0800 Subject: [PATCH 12/19] add source type for ssrf --- .../hookpoint/controller/impl/SourceImpl.java | 55 +++++---- .../hookpoint/graphy/GraphBuilder.java | 3 +- .../handler/hookpoint/graphy/GraphNode.java | 14 ++- .../handler/hookpoint/models/MethodEvent.java | 19 +++ .../dynamic/DynamicPropagatorScanner.java | 45 ++++--- .../vulscan/dynamic/SSRFSourceCheck.java | 114 ++++++++++++++++++ .../taintrange/TaintRangesBuilder.java | 22 +++- 7 files changed, 220 insertions(+), 52 deletions(-) create mode 100644 dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/SSRFSourceCheck.java diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/controller/impl/SourceImpl.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/controller/impl/SourceImpl.java index 54180d67e..328985645 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/controller/impl/SourceImpl.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/controller/impl/SourceImpl.java @@ -47,18 +47,17 @@ public static void solveSource(MethodEvent event, AtomicInteger invokeIdSequence } private static void trackTarget(MethodEvent event) { - TaintRangesBuilder tb = new TaintRangesBuilder(); - int length = tb.getLength(event.returnValue); + int length = TaintRangesBuilder.getLength(event.returnValue); if (length == 0) { return; } - trackObject(tb, event, event.returnValue, 0); + trackObject(event, event.returnValue, 0); // @TODO: hook json serializer for custom model - handlerCustomModel(tb, event); + handlerCustomModel(event); } - private static void trackObject(TaintRangesBuilder tb, MethodEvent event, Object obj, int depth) { + private static void trackObject(MethodEvent event, Object obj, int depth) { if (depth >= 10 || !TaintPoolUtils.isNotEmpty(obj) || !TaintPoolUtils.isAllowTaintType(obj)) { return; } @@ -70,21 +69,21 @@ private static void trackObject(TaintRangesBuilder tb, MethodEvent event, Object Class cls = obj.getClass(); if (cls.isArray() && !cls.getComponentType().isPrimitive()) { - trackArray(tb, event, obj, depth); + trackArray(event, obj, depth); } else if (obj instanceof Iterator) { - trackIterator(tb, event, (Iterator) obj, depth); + trackIterator(event, (Iterator) obj, depth); } else if (obj instanceof Map) { - trackMap(tb, event, (Map) obj, depth); + trackMap(event, (Map) obj, depth); } else if (obj instanceof Map.Entry) { - trackMapEntry(tb, event, (Map.Entry) obj, depth); + trackMapEntry(event, (Map.Entry) obj, depth); } else if (obj instanceof Collection) { if (obj instanceof List) { - trackList(tb, event, (List) obj, depth); + trackList(event, (List) obj, depth); } else { - trackIterator(tb, event, ((Collection) obj).iterator(), depth); + trackIterator(event, ((Collection) obj).iterator(), depth); } } else if ("java.util.Optional".equals(obj.getClass().getName())) { - trackOptional(tb, event, obj, depth); + trackOptional(event, obj, depth); } else { int len = TaintRangesBuilder.getLength(obj); if (len == 0) { @@ -101,41 +100,41 @@ private static void trackObject(TaintRangesBuilder tb, MethodEvent event, Object } } - private static void trackArray(TaintRangesBuilder tb, MethodEvent event, Object arr, int depth) { + private static void trackArray(MethodEvent event, Object arr, int depth) { int length = Array.getLength(arr); for (int i = 0; i < length; i++) { - trackObject(tb, event, Array.get(arr, i), depth); + trackObject(event, Array.get(arr, i), depth); } } - private static void trackIterator(TaintRangesBuilder tb, MethodEvent event, Iterator it, int depth) { + private static void trackIterator(MethodEvent event, Iterator it, int depth) { while (it.hasNext()) { - trackObject(tb, event, it.next(), depth + 1); + trackObject(event, it.next(), depth + 1); } } - private static void trackMap(TaintRangesBuilder tb, MethodEvent event, Map map, int depth) { + private static void trackMap(MethodEvent event, Map map, int depth) { for (Object key : map.keySet()) { - trackObject(tb, event, key, depth); - trackObject(tb, event, map.get(key), depth); + trackObject(event, key, depth); + trackObject(event, map.get(key), depth); } } - private static void trackMapEntry(TaintRangesBuilder tb, MethodEvent event, Map.Entry entry, int depth) { - trackObject(tb, event, entry.getKey(), depth + 1); - trackObject(tb, event, entry.getValue(), depth + 1); + private static void trackMapEntry(MethodEvent event, Map.Entry entry, int depth) { + trackObject(event, entry.getKey(), depth + 1); + trackObject(event, entry.getValue(), depth + 1); } - private static void trackList(TaintRangesBuilder tb, MethodEvent event, List list, int depth) { + private static void trackList(MethodEvent event, List list, int depth) { for (Object obj : list) { - trackObject(tb, event, obj, depth); + trackObject(event, obj, depth); } } - private static void trackOptional(TaintRangesBuilder tb, MethodEvent event, Object obj, int depth) { + private static void trackOptional(MethodEvent event, Object obj, int depth) { try { Object v = ((Optional) obj).orElse(null); - trackObject(tb, event, v, depth); + trackObject(event, v, depth); } catch (Exception e) { DongTaiLog.warn("track optional object failed: " + e.getMessage()); } @@ -146,11 +145,11 @@ private static void trackOptional(TaintRangesBuilder tb, MethodEvent event, Obje * * @param event MethodEvent */ - public static void handlerCustomModel(TaintRangesBuilder tb, MethodEvent event) { + public static void handlerCustomModel(MethodEvent event) { if (!event.getMethodName().equals("getSession")) { Set modelValues = parseCustomModel(event.returnValue); for (Object modelValue : modelValues) { - trackObject(tb, event, modelValue, 0); + trackObject(event, modelValue, 0); } } } diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/graphy/GraphBuilder.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/graphy/GraphBuilder.java index de1a5773a..694c197b1 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/graphy/GraphBuilder.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/graphy/GraphBuilder.java @@ -72,7 +72,8 @@ public static List build() { event.getServiceName(), event.getPlugin(), event.getProjectPropagatorClose(), - event.targetRanges + event.targetRanges, + event.sourceTypes ) ); }catch (Exception e){ diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/graphy/GraphNode.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/graphy/GraphNode.java index 4b5ebf362..1bcee6e07 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/graphy/GraphNode.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/graphy/GraphNode.java @@ -118,6 +118,8 @@ public void setInterfaceNames(Set interfaceNames) { private List targetRanges = new ArrayList(); + public List sourceTypes; + public GraphNode(boolean isSource, int invokeId, String callerClass, @@ -142,7 +144,8 @@ public GraphNode(boolean isSource, String serviceName, String plugin, Boolean projectPropagatorClose, - List targetRanges + List targetRanges, + List sourceTypes ) { this.isSource = isSource; this.invokeId = invokeId; @@ -169,6 +172,7 @@ public GraphNode(boolean isSource, this.plugin = plugin; this.projectPropagatorClose = projectPropagatorClose; this.targetRanges = targetRanges; + this.sourceTypes = sourceTypes; } public JSONObject toJson() { @@ -233,6 +237,14 @@ public JSONObject toJson() { tr.put(range.toJson()); } + if (sourceTypes != null && sourceTypes.size() > 0) { + JSONArray st = new JSONArray(); + value.put("sourceType", st); + for (MethodEvent.MethodEventSourceType s : sourceTypes) { + st.put(s.toJson()); + } + } + return value; } } diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/models/MethodEvent.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/models/MethodEvent.java index b790dac71..a718888e2 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/models/MethodEvent.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/models/MethodEvent.java @@ -206,6 +206,25 @@ public void setProjectPropagatorClose(Boolean projectPropagatorClose) { public List targetRanges = new ArrayList(); + public List sourceTypes; + + public static class MethodEventSourceType { + private final Integer hash; + private final String type; + + public MethodEventSourceType(Integer hash, String type) { + this.hash = hash; + this.type = type; + } + + public JSONObject toJson() { + JSONObject json = new JSONObject(); + json.put("hash", this.hash); + json.put("type", this.type); + return json; + } + } + public static class MethodEventTargetRange { private final Integer hash; private final String value; diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/DynamicPropagatorScanner.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/DynamicPropagatorScanner.java index 8e1a09116..16f2de3dd 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/DynamicPropagatorScanner.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/DynamicPropagatorScanner.java @@ -95,28 +95,33 @@ private boolean sinkSourceHitTaintPool(MethodEvent event, IastSinkModel sink) { Object attributeValue = event.argumentArray[1]; hitTaintPool = TaintPoolUtils.poolContains(attributeValue, event); } - } else { - int[] taintPositionIndexArray = sink.getPos(); - - if (taintPositionIndexArray != null) { - Object sourceValue = null; - for (int index : taintPositionIndexArray) { - if (event.argumentArray.length > index) { - hitTaintPool = TaintPoolUtils.poolContains(event.argumentArray[index], event); - if (hitTaintPool) { - sourceValue = event.argumentArray[index]; - break; - } + return hitTaintPool; + } + + if (SSRFSourceCheck.isSinkMethod(sink)) { + return SSRFSourceCheck.sourceHitTaintPool(event, sink); + } + + int[] taintPositionIndexArray = sink.getPos(); + + if (taintPositionIndexArray != null) { + Object sourceValue = null; + for (int index : taintPositionIndexArray) { + if (event.argumentArray.length > index) { + hitTaintPool = TaintPoolUtils.poolContains(event.argumentArray[index], event); + if (hitTaintPool) { + sourceValue = event.argumentArray[index]; + break; } } - if (hitTaintPool) { - event.setInValue(sourceValue); - } - } else { - hitTaintPool = TaintPoolUtils.poolContains(event.object, event); - if (hitTaintPool) { - event.setInValue(event.object); - } + } + if (hitTaintPool) { + event.setInValue(sourceValue); + } + } else { + hitTaintPool = TaintPoolUtils.poolContains(event.object, event); + if (hitTaintPool) { + event.setInValue(event.object); } } return hitTaintPool; diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/SSRFSourceCheck.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/SSRFSourceCheck.java new file mode 100644 index 000000000..d37ead25d --- /dev/null +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/SSRFSourceCheck.java @@ -0,0 +1,114 @@ +package io.dongtai.iast.core.handler.hookpoint.vulscan.dynamic; + +import io.dongtai.iast.core.handler.hookpoint.models.IastSinkModel; +import io.dongtai.iast.core.handler.hookpoint.models.MethodEvent; +import io.dongtai.iast.core.utils.TaintPoolUtils; +import io.dongtai.log.DongTaiLog; + +import java.net.URI; +import java.net.URL; +import java.util.*; + +public class SSRFSourceCheck { + private static final String JAVA_NET_URL_OPEN_CONNECTION = "java.net.URL.openConnection()"; + private static final String JAVA_NET_URL_OPEN_CONNECTION_PROXY = "java.net.URL.openConnection(java.net.Proxy)"; + private static final String JAVA_NET_URL_OPEN_STREAM = "java.net.URL.openStream()"; + + private static final String APACHE_HTTP_CLIENT_REQUEST_SET_URI = " org.apache.http.client.methods.HttpRequestBase.setURI(java.net.URI)".substring(1); + + + private static final Set SSRF_SINK_METHODS = new HashSet<>(Arrays.asList( + JAVA_NET_URL_OPEN_CONNECTION, + JAVA_NET_URL_OPEN_CONNECTION_PROXY, + JAVA_NET_URL_OPEN_STREAM, + APACHE_HTTP_CLIENT_REQUEST_SET_URI + )); + + public static boolean isSinkMethod(IastSinkModel sink) { + return SSRF_SINK_METHODS.contains(sink.getSignature()); + } + + public static boolean sourceHitTaintPool(MethodEvent event, IastSinkModel sink) { + boolean hitTaintPool = false; + if (JAVA_NET_URL_OPEN_CONNECTION.equals(sink.getSignature()) + || JAVA_NET_URL_OPEN_CONNECTION_PROXY.equals(sink.getSignature()) + || JAVA_NET_URL_OPEN_STREAM.equals(sink.getSignature())) { + return javaNetURLSourceHit(event, sink); + } else if (APACHE_HTTP_CLIENT_REQUEST_SET_URI.equals(sink.getSignature())) { + return apacheHttpClientRequestSetURISourceHit(event, sink); + } + return hitTaintPool; + } + + private static boolean javaNetURLSourceHit(MethodEvent event, IastSinkModel sink) { + try { + if (!(event.object instanceof URL)) { + return false; + } + + URL url = (URL) event.object; + String protocol = url.getProtocol(); + String userInfo = url.getUserInfo(); + String host = url.getHost(); + String path = url.getPath(); + String query = url.getQuery(); + + event.inValue = url.toString(); + return addSourceType(event, protocol, userInfo, host, path, query); + } catch (Exception e) { + DongTaiLog.warn("java.net.URL get protocol and host failed: " + e.getMessage()); + return false; + } + } + + private static boolean apacheHttpClientRequestSetURISourceHit(MethodEvent event, IastSinkModel sink) { + try { + if (event.argumentArray.length < 1 || !(event.argumentArray[0] instanceof URI)) { + return false; + } + + URI uri = (URI) event.argumentArray[0]; + + String protocol = uri.getScheme(); + String authority = uri.getUserInfo(); + String host = uri.getHost(); + String path = uri.getPath(); + String query = uri.getPath(); + + event.inValue = uri.toString(); + return addSourceType(event, protocol, authority, host, path, query); + } catch (Exception e) { + DongTaiLog.warn("apache http client get protocol and host failed: " + e.getMessage()); + return false; + } + } + + private static boolean addSourceType(MethodEvent event, String protocol, String userInfo, String host, String path, String query) { + boolean hit1 = !"".equals(protocol) && TaintPoolUtils.poolContains(protocol, event); + boolean hit2 = !"".equals(userInfo) && TaintPoolUtils.poolContains(userInfo, event); + boolean hit3 = !"".equals(host) && TaintPoolUtils.poolContains(host, event); + boolean hit4 = !"".equals(path) && TaintPoolUtils.poolContains(path, event); + boolean hit5 = !"".equals(query) && TaintPoolUtils.poolContains(query, event); + event.inValue = event.object.toString(); + boolean hit = hit1 || hit2 || hit3 || hit4 || hit5; + if (hit && event.sourceTypes == null) { + event.sourceTypes = new ArrayList(); + if (hit1) { + event.sourceTypes.add(new MethodEvent.MethodEventSourceType(System.identityHashCode(protocol), "PROTOCOL")); + } + if (hit2) { + event.sourceTypes.add(new MethodEvent.MethodEventSourceType(System.identityHashCode(userInfo), "USERINFO")); + } + if (hit3) { + event.sourceTypes.add(new MethodEvent.MethodEventSourceType(System.identityHashCode(host), "HOST")); + } + if (hit4) { + event.sourceTypes.add(new MethodEvent.MethodEventSourceType(System.identityHashCode(path), "PATH")); + } + if (hit5) { + event.sourceTypes.add(new MethodEvent.MethodEventSourceType(System.identityHashCode(query), "QUERY")); + } + } + return hit; + } +} diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesBuilder.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesBuilder.java index 4f8c5dac6..697d4a6c5 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesBuilder.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintRangesBuilder.java @@ -177,9 +177,9 @@ public static String obj2String(Object obj) { } else if (obj instanceof Character) { return ((Character) obj).toString(); } else if (obj instanceof byte[]) { - return new String((byte[]) obj); + return trimRight((byte[]) obj); } else if (obj instanceof char[]) { - return new String((char[]) obj); + return trimRight((char[]) obj); } else { return (obj.getClass().getName() + "@" + Integer.toHexString(obj.hashCode())); } @@ -218,4 +218,22 @@ public static int getLength(Object obj) { return (obj.getClass().getName() + "@" + Integer.toHexString(obj.hashCode())).length(); } } + + public static String trimRight(char[] value) { + int len = value.length; + char[] val = value; + while ((len > 0) && (val[len - 1] <= ' ')) { + len--; + } + return new String(value, 0, len); + } + + public static String trimRight(byte[] value) { + int len = value.length; + byte[] val = value; + while ((len > 0) && (val[len - 1] <= ' ')) { + len--; + } + return new String(value, 0, len); + } } From 28d084dd7de7c0e2b266becb1f419707dd74c37c Mon Sep 17 00:00:00 2001 From: lostsnow Date: Fri, 26 Aug 2022 19:06:46 +0800 Subject: [PATCH 13/19] ssrf check for apache legacy http client --- .../vulscan/dynamic/SSRFSourceCheck.java | 47 +++++++++++++------ 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/SSRFSourceCheck.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/SSRFSourceCheck.java index d37ead25d..97897401c 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/SSRFSourceCheck.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/SSRFSourceCheck.java @@ -14,14 +14,16 @@ public class SSRFSourceCheck { private static final String JAVA_NET_URL_OPEN_CONNECTION_PROXY = "java.net.URL.openConnection(java.net.Proxy)"; private static final String JAVA_NET_URL_OPEN_STREAM = "java.net.URL.openStream()"; + // TODO: use method execute for sink private static final String APACHE_HTTP_CLIENT_REQUEST_SET_URI = " org.apache.http.client.methods.HttpRequestBase.setURI(java.net.URI)".substring(1); - + private static final String APACHE_LEGACY_HTTP_CLIENT_REQUEST_SET_URI = " org.apache.commons.httpclient.HttpMethodBase.setURI(org.apache.commons.httpclient.HttpMethodBase.URI)".substring(1); private static final Set SSRF_SINK_METHODS = new HashSet<>(Arrays.asList( JAVA_NET_URL_OPEN_CONNECTION, JAVA_NET_URL_OPEN_CONNECTION_PROXY, JAVA_NET_URL_OPEN_STREAM, - APACHE_HTTP_CLIENT_REQUEST_SET_URI + APACHE_HTTP_CLIENT_REQUEST_SET_URI, + APACHE_LEGACY_HTTP_CLIENT_REQUEST_SET_URI )); public static boolean isSinkMethod(IastSinkModel sink) { @@ -34,7 +36,8 @@ public static boolean sourceHitTaintPool(MethodEvent event, IastSinkModel sink) || JAVA_NET_URL_OPEN_CONNECTION_PROXY.equals(sink.getSignature()) || JAVA_NET_URL_OPEN_STREAM.equals(sink.getSignature())) { return javaNetURLSourceHit(event, sink); - } else if (APACHE_HTTP_CLIENT_REQUEST_SET_URI.equals(sink.getSignature())) { + } else if (APACHE_HTTP_CLIENT_REQUEST_SET_URI.equals(sink.getSignature()) + || APACHE_LEGACY_HTTP_CLIENT_REQUEST_SET_URI.equals(sink.getSignature())) { return apacheHttpClientRequestSetURISourceHit(event, sink); } return hitTaintPool; @@ -56,29 +59,43 @@ private static boolean javaNetURLSourceHit(MethodEvent event, IastSinkModel sink event.inValue = url.toString(); return addSourceType(event, protocol, userInfo, host, path, query); } catch (Exception e) { - DongTaiLog.warn("java.net.URL get protocol and host failed: " + e.getMessage()); + DongTaiLog.warn("java.net.URL get source failed: " + e.getMessage()); return false; } } private static boolean apacheHttpClientRequestSetURISourceHit(MethodEvent event, IastSinkModel sink) { try { - if (event.argumentArray.length < 1 || !(event.argumentArray[0] instanceof URI)) { + if (event.argumentArray.length < 1 || event.argumentArray[0] == null) { return false; } - URI uri = (URI) event.argumentArray[0]; - - String protocol = uri.getScheme(); - String authority = uri.getUserInfo(); - String host = uri.getHost(); - String path = uri.getPath(); - String query = uri.getPath(); + Object obj = event.argumentArray[0]; + if (event.argumentArray[0] instanceof URI) { + URI uri = (URI) obj; + + String protocol = uri.getScheme(); + String userInfo = uri.getUserInfo(); + String host = uri.getHost(); + String path = uri.getPath(); + String query = uri.getQuery(); + + event.inValue = uri.toString(); + return addSourceType(event, protocol, userInfo, host, path, query); + } else if ("org.apache.commons.httpclient.HttpMethodBase".equals(obj.getClass().getName())) { + String protocol = (String) obj.getClass().getMethod("getScheme").invoke(obj); + String userInfo = (String) obj.getClass().getMethod("getUserinfo").invoke(obj); + String host = (String) obj.getClass().getMethod("getHost").invoke(obj); + String path = (String) obj.getClass().getMethod("getPath").invoke(obj); + String query = (String) obj.getClass().getMethod("getQuery").invoke(obj); + + event.inValue = (String) obj.getClass().getMethod("toString").invoke(obj); + return addSourceType(event, protocol, userInfo, host, path, query); + } - event.inValue = uri.toString(); - return addSourceType(event, protocol, authority, host, path, query); + return false; } catch (Exception e) { - DongTaiLog.warn("apache http client get protocol and host failed: " + e.getMessage()); + DongTaiLog.warn("apache http client get source failed: " + e.getMessage()); return false; } } From 5ecc9016957cd272e815628e7d3f0f50f38a6bcf Mon Sep 17 00:00:00 2001 From: lostsnow Date: Mon, 29 Aug 2022 10:23:42 +0800 Subject: [PATCH 14/19] enable java/lang/StringBuffer hook --- .../src/main/resources/com.secnium.iast.resources/blacklist.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dongtai-core/src/main/resources/com.secnium.iast.resources/blacklist.txt b/dongtai-core/src/main/resources/com.secnium.iast.resources/blacklist.txt index d39d424a6..5f3730f2f 100644 --- a/dongtai-core/src/main/resources/com.secnium.iast.resources/blacklist.txt +++ b/dongtai-core/src/main/resources/com.secnium.iast.resources/blacklist.txt @@ -23792,7 +23792,7 @@ java/lang/SecurityManager #java/lang/String java/lang/String$1 java/lang/String$CaseInsensitiveComparator -java/lang/StringBuffer +#java/lang/StringBuffer #java/lang/StringBuilder java/lang/StringCoding java/lang/StringCoding$1 From 31d67955b403143ce32bfee9400d763cb7b402ee Mon Sep 17 00:00:00 2001 From: lostsnow Date: Tue, 30 Aug 2022 18:20:36 +0800 Subject: [PATCH 15/19] fixes taint range rules --- .../taintrange/TaintCommandRunner.java | 210 +++++++++--------- 1 file changed, 105 insertions(+), 105 deletions(-) diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommandRunner.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommandRunner.java index 92a8dcc9f..5f15f7c34 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommandRunner.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommandRunner.java @@ -125,199 +125,199 @@ public static TaintCommandRunner getCommandRunner(String signature) { private static final Map RUNNER_MAP = new HashMap() {{ // KEEP String String METHOD = "java.lang.String.(java.lang.String)"; - put(METHOD, create(METHOD, TaintCommand.KEEP)); + put(METHOD, create(METHOD, TaintCommand.KEEP)); // P1=>O METHOD = "java.lang.String.(java.lang.StringBuilder)"; - put(METHOD, create(METHOD, TaintCommand.KEEP)); + put(METHOD, create(METHOD, TaintCommand.KEEP)); // P1=>O METHOD = "java.lang.String.(java.lang.StringBuffer)"; - put(METHOD, create(METHOD, TaintCommand.KEEP)); + put(METHOD, create(METHOD, TaintCommand.KEEP)); // P1=>O METHOD = "java.lang.String.(byte[],int,int)"; - put(METHOD, create(METHOD, TaintCommand.KEEP)); + put(METHOD, create(METHOD, TaintCommand.KEEP)); // P1=>O METHOD = "java.lang.String.(byte[],int,int,int)"; - put(METHOD, create(METHOD, TaintCommand.KEEP)); + put(METHOD, create(METHOD, TaintCommand.KEEP)); // P1=>O METHOD = "java.lang.String.(byte[],int,int,java.lang.String)"; - put(METHOD, create(METHOD, TaintCommand.KEEP)); + put(METHOD, create(METHOD, TaintCommand.KEEP)); // P1=>O METHOD = "java.lang.String.(char[])"; - put(METHOD, create(METHOD, TaintCommand.KEEP)); - METHOD = "java.lang.String.(byte[],java.nio.charset.Charset)"; // Java-11 - put(METHOD, create(METHOD, TaintCommand.KEEP)); - METHOD = "java.lang.String.(byte[],byte)"; // Java-17 - put(METHOD, create(METHOD, TaintCommand.KEEP)); + put(METHOD, create(METHOD, TaintCommand.KEEP)); // P1=>O + METHOD = "java.lang.String.(byte[],java.nio.charset.Charset)"; + put(METHOD, create(METHOD, TaintCommand.KEEP)); // P1=>O + METHOD = "java.lang.String.(byte[],byte)"; // Java-17 + put(METHOD, create(METHOD, TaintCommand.KEEP)); // P1=>O METHOD = "java.lang.String.toLowerCase(java.util.Locale)"; - put(METHOD, create(METHOD, TaintCommand.KEEP)); + put(METHOD, create(METHOD, TaintCommand.KEEP)); // O=>R METHOD = "java.lang.String.toUpperCase(java.util.Locale)"; - put(METHOD, create(METHOD, TaintCommand.KEEP)); + put(METHOD, create(METHOD, TaintCommand.KEEP)); // O=>R METHOD = "java.lang.String.getBytes()"; - put(METHOD, create(METHOD, TaintCommand.KEEP)); + put(METHOD, create(METHOD, TaintCommand.KEEP)); // O=>R METHOD = "java.lang.String.getBytes(java.lang.String)"; - put(METHOD, create(METHOD, TaintCommand.KEEP)); + put(METHOD, create(METHOD, TaintCommand.KEEP)); // O=>R METHOD = "java.lang.String.getBytes(java.nio.charset.Charset)"; - put(METHOD, create(METHOD, TaintCommand.KEEP)); + put(METHOD, create(METHOD, TaintCommand.KEEP)); // O=>R METHOD = "java.lang.String.toCharArray()"; - put(METHOD, create(METHOD, TaintCommand.KEEP)); + put(METHOD, create(METHOD, TaintCommand.KEEP)); // O=>R // KEEP StringBuilder METHOD = "java.lang.StringBuilder.toString()"; - put(METHOD, create(METHOD, TaintCommand.KEEP)); + put(METHOD, create(METHOD, TaintCommand.KEEP)); // O=>R METHOD = "java.lang.StringBuilder.(java.lang.String)"; - put(METHOD, create(METHOD, TaintCommand.KEEP)); + put(METHOD, create(METHOD, TaintCommand.KEEP)); // P1=>O METHOD = "java.lang.StringBuilder.(java.lang.CharSequence)"; - put(METHOD, create(METHOD, TaintCommand.KEEP)); + put(METHOD, create(METHOD, TaintCommand.KEEP)); // P1=>O // KEEP StringBuffer METHOD = "java.lang.StringBuffer.toString()"; - put(METHOD, create(METHOD, TaintCommand.KEEP)); + put(METHOD, create(METHOD, TaintCommand.KEEP)); // O=>R METHOD = "java.lang.StringBuffer.(java.lang.String)"; - put(METHOD, create(METHOD, TaintCommand.KEEP)); + put(METHOD, create(METHOD, TaintCommand.KEEP)); // P1=>O METHOD = "java.lang.StringBuffer.(java.lang.CharSequence)"; - put(METHOD, create(METHOD, TaintCommand.KEEP)); + put(METHOD, create(METHOD, TaintCommand.KEEP)); // P1=>O // KEEP ByteArrayOutputStream METHOD = "java.io.ByteArrayOutputStream.toByteArray()"; - put(METHOD, create(METHOD, TaintCommand.KEEP)); + put(METHOD, create(METHOD, TaintCommand.KEEP)); // O=>R METHOD = "java.io.ByteArrayOutputStream.toString()"; - put(METHOD, create(METHOD, TaintCommand.KEEP)); + put(METHOD, create(METHOD, TaintCommand.KEEP)); // O=>R METHOD = "java.io.ByteArrayOutputStream.toString(java.lang.String)"; - put(METHOD, create(METHOD, TaintCommand.KEEP)); + put(METHOD, create(METHOD, TaintCommand.KEEP)); // O=>R METHOD = "java.io.ByteArrayOutputStream.toString(int)"; - put(METHOD, create(METHOD, TaintCommand.KEEP)); + put(METHOD, create(METHOD, TaintCommand.KEEP)); // O=>R METHOD = "java.io.ByteArrayOutputStream.toString(java.nio.charset.Charset)"; - put(METHOD, create(METHOD, TaintCommand.KEEP)); + put(METHOD, create(METHOD, TaintCommand.KEEP)); // O=>R // KEEP StringConcatHelper METHOD = "java.lang.StringConcatHelper.newString(byte[],int,byte)"; // Java 9-11 - put(METHOD, create(METHOD, TaintCommand.KEEP)); + put(METHOD, create(METHOD, TaintCommand.KEEP)); // P1=>R METHOD = "java.lang.StringConcatHelper.newString(byte[],long)"; // Java 12+, up to 14 - put(METHOD, create(METHOD, TaintCommand.KEEP)); + put(METHOD, create(METHOD, TaintCommand.KEEP)); // P1=>R // KEEP StringWriter METHOD = "java.io.StringWriter.toString()"; - put(METHOD, create(METHOD, TaintCommand.KEEP)); + put(METHOD, create(METHOD, TaintCommand.KEEP)); // O=>R // APPEND String METHOD = "java.lang.String.(char[],int,int)"; - put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3", "0"))); + put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3", "0"))); // P1=>O METHOD = "java.lang.String.(char[],int,int,boolean)"; // in IBM JDK8 split() - put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3", "0"))); + put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3", "0"))); // P1=>O // APPEND StringLatin1/StringUTF16 METHOD = "java.lang.StringLatin1.newString(byte[],int,int)"; // Java-11 - put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3", "0"))); + put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3", "0"))); // P1=>R METHOD = "java.lang.StringUTF16.newString(byte[],int,int)"; // Java-11 - put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3", "0"))); + put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3", "0"))); // P1=>R // APPEND StringBuilder METHOD = "java.lang.StringBuilder.append(java.lang.String)"; - put(METHOD, create(METHOD, TaintCommand.APPEND)); + put(METHOD, create(METHOD, TaintCommand.APPEND)); // P1=>O METHOD = "java.lang.StringBuilder.append(java.lang.StringBuffer)"; - put(METHOD, create(METHOD, TaintCommand.APPEND)); + put(METHOD, create(METHOD, TaintCommand.APPEND)); // P1=>O METHOD = "java.lang.StringBuilder.append(java.lang.CharSequence)"; - put(METHOD, create(METHOD, TaintCommand.APPEND)); + put(METHOD, create(METHOD, TaintCommand.APPEND)); // P1=>O METHOD = "java.lang.StringBuilder.append(java.lang.CharSequence,int,int)"; - put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3"))); + put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3"))); // P1=>O METHOD = "java.lang.StringBuilder.append(char[],int,int)"; - put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3", "0"))); + put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3", "0"))); // P1=>O // APPEND AbstractStringBuilder METHOD = "java.lang.AbstractStringBuilder.append(java.lang.String)"; - put(METHOD, create(METHOD, TaintCommand.APPEND)); + put(METHOD, create(METHOD, TaintCommand.APPEND)); // P1=>O // APPEND StringBuffer METHOD = "java.lang.StringBuffer.append(java.lang.String)"; - put(METHOD, create(METHOD, TaintCommand.APPEND)); + put(METHOD, create(METHOD, TaintCommand.APPEND)); // P1=>O METHOD = "java.lang.StringBuffer.append(java.lang.StringBuffer)"; - put(METHOD, create(METHOD, TaintCommand.APPEND)); + put(METHOD, create(METHOD, TaintCommand.APPEND)); // P1=>O METHOD = "java.lang.StringBuffer.append(char[])"; - put(METHOD, create(METHOD, TaintCommand.APPEND)); + put(METHOD, create(METHOD, TaintCommand.APPEND)); // P1=>O METHOD = "java.lang.StringBuffer.append(java.lang.CharSequence)"; - put(METHOD, create(METHOD, TaintCommand.APPEND)); + put(METHOD, create(METHOD, TaintCommand.APPEND)); // P1=>O METHOD = "java.lang.StringBuffer.append(java.lang.CharSequence,int,int)"; - put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3"))); + put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3"))); // P1=>O METHOD = "java.lang.StringBuffer.append(char[],int,int)"; - put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3", "0"))); + put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3", "0"))); // P1=>O // APPEND ByteArrayOutputStream - METHOD = "java.io.ByteArrayOutputStream.toString(java.nio.charset.Charset)"; - put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3"))); + METHOD = "java.io.ByteArrayOutputStream.write(byte[],int,int)"; + put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3"))); // P1=>O + + // APPEND apache ByteArrayOutputStream + METHOD = " org.apache.commons.io.output.ByteArrayOutputStream.write(byte[],int,int)".substring(1); + put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3"))); // P1=>O // APPEND StringWriter METHOD = "java.io.StringWriter.write(char[],int,int)"; - put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3"))); + put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3"))); // P1=>O METHOD = "java.io.StringWriter.write(java.lang.String)"; put(METHOD, create(METHOD, TaintCommand.APPEND)); METHOD = "java.io.StringWriter.write(java.lang.String,int,int)"; put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3"))); - // APPEND apache ByteArrayOutputStream - METHOD = "org.apache.commons.io.output.ByteArrayOutputStream.write(byte[],int,int)"; - put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3"))); - // SUBSET String METHOD = "java.lang.String.substring(int)"; - put(METHOD, create(METHOD, TaintCommand.SUBSET, Collections.singletonList("P1"))); + put(METHOD, create(METHOD, TaintCommand.SUBSET, Collections.singletonList("P1"))); // O=>R METHOD = "java.lang.String.substring(int,int)"; - put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P1", "P2"))); + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P1", "P2"))); // O=>R METHOD = "java.lang.String.getBytes(int,int,byte[],int)"; - put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P1", "P2", "P4"))); + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P1", "P2", "P4"))); // O=>P3 METHOD = "java.lang.String.getChars(int,int,char[],int)"; - put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P1", "P2", "P4"))); + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P1", "P2", "P4"))); // O=>P3 METHOD = "java.lang.String.(byte[],int,int,java.nio.charset.Charset)"; - put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P2", "P3"))); + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P2", "P3"))); // P1=>O // SUBSET StringLatin1/StringUTF16 LinesSpliterator METHOD = "java.lang.StringLatin1$LinesSpliterator.(byte[],int,int)"; // Java-11 - put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P2", "P3"))); + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P2", "P3"))); // P1=>O METHOD = "java.lang.StringUTF16$LinesSpliterator.(byte[],int,int)"; // Java-11 - put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P2", "P3"))); + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P2", "P3"))); // P1=>O // SUBSET StringBuilder METHOD = "java.lang.StringBuilder.substring(int)"; - put(METHOD, create(METHOD, TaintCommand.SUBSET, Collections.singletonList("P1"))); + put(METHOD, create(METHOD, TaintCommand.SUBSET, Collections.singletonList("P1"))); // O=>R METHOD = "java.lang.StringBuilder.substring(int,int)"; - put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P1", "P2"))); + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P1", "P2"))); // O=>R METHOD = "java.lang.StringBuilder.setLength(int)"; - put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("0", "P1"))); + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("0", "P1"))); // O=>O METHOD = "java.lang.StringBuilder.getChars(int,int,char[],int)"; - put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P1", "P2", "P4"))); + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P1", "P2", "P4"))); // O=>P3 // SUBSET AbstractStringBuilder METHOD = "java.lang.AbstractStringBuilder.substring(int)"; - put(METHOD, create(METHOD, TaintCommand.SUBSET, Collections.singletonList("P1"))); + put(METHOD, create(METHOD, TaintCommand.SUBSET, Collections.singletonList("P1"))); // O=>R METHOD = "java.lang.AbstractStringBuilder.substring(int,int)"; - put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P1", "P2"))); + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P1", "P2"))); // O=>R METHOD = "java.lang.AbstractStringBuilder.setLength(int)"; - put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("0", "P1"))); + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("0", "P1"))); // O=>O METHOD = "java.lang.AbstractStringBuilder.getChars(int,int,char[],int)"; - put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P1", "P2", "P4"))); + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P1", "P2", "P4"))); // O=>P3 // SUBSET StringBuffer METHOD = "java.lang.StringBuffer.substring(int)"; - put(METHOD, create(METHOD, TaintCommand.SUBSET, Collections.singletonList("P1"))); + put(METHOD, create(METHOD, TaintCommand.SUBSET, Collections.singletonList("P1"))); // O=>R METHOD = "java.lang.StringBuffer.substring(int,int)"; - put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P1", "P2"))); + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P1", "P2"))); // O=>R METHOD = "java.lang.StringBuffer.setLength(int)"; - put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("0", "P1"))); + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("0", "P1"))); // O=>O METHOD = "java.lang.StringBuffer.getChars(int,int,char[],int)"; - put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P1", "P2", "P4"))); + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P1", "P2", "P4"))); // O=>P3 // SUBSET ByteBuffer METHOD = "java.nio.ByteBuffer.wrap(byte[],int,int)"; - put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P2", "P3"))); + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P2", "P3"))); // P1=>R // SUBSET Arrays METHOD = "java.util.Arrays.copyOf(byte[],int)"; - put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("0", "P2"))); + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("0", "P2"))); // P1=>R METHOD = "java.util.Arrays.copyOfRange(byte[],int,int)"; - put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P2", "P3"))); + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P2", "P3"))); // P1=>R METHOD = "java.util.Arrays.copyOf(char[],int)"; - put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("0", "P2"))); + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("0", "P2"))); // P1=>R METHOD = "java.util.Arrays.copyOfRange(char[],int,int)"; - put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P2", "P3"))); + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P2", "P3"))); // P1=>R // INSERT CharArrayReader/PipedReader/PipedInputStream METHOD = "java.io.CharArrayReader.(char[],int,int)"; - put(METHOD, create(METHOD, TaintCommand.INSERT, Arrays.asList("0", "P2", "P3"))); + put(METHOD, create(METHOD, TaintCommand.INSERT, Arrays.asList("0", "P2", "P3"))); // P1=>O METHOD = "java.io.CharArrayReader.read(char[],int,int)"; - put(METHOD, create(METHOD, TaintCommand.INSERT, Arrays.asList("0", "P2", "P3"))); + put(METHOD, create(METHOD, TaintCommand.INSERT, Arrays.asList("0", "P2", "P3"))); // O=>P1 METHOD = "java.io.PipedReader.read(char[],int,int)"; put(METHOD, create(METHOD, TaintCommand.INSERT, Arrays.asList("0", "P2", "P3"))); METHOD = "java.io.PipedInputStream.read(byte[],int,int)"; @@ -325,60 +325,60 @@ public static TaintCommandRunner getCommandRunner(String signature) { // INSERT StringBuilder METHOD = "java.lang.StringBuilder.insert(int,java.lang.String)"; - put(METHOD, create(METHOD, TaintCommand.INSERT, Collections.singletonList("P1"))); + put(METHOD, create(METHOD, TaintCommand.INSERT, Collections.singletonList("P1"))); // P2=>O METHOD = "java.lang.StringBuilder.insert(int,char[])"; - put(METHOD, create(METHOD, TaintCommand.INSERT, Collections.singletonList("P1"))); + put(METHOD, create(METHOD, TaintCommand.INSERT, Collections.singletonList("P1"))); // P2=>O METHOD = "java.lang.StringBuilder.insert(int,char)"; - put(METHOD, create(METHOD, TaintCommand.INSERT, Collections.singletonList("P1"))); + put(METHOD, create(METHOD, TaintCommand.INSERT, Collections.singletonList("P1"))); // P2=>O METHOD = "java.lang.StringBuilder.insert(int,java.lang.CharSequence)"; - put(METHOD, create(METHOD, TaintCommand.INSERT, Collections.singletonList("P1"))); + put(METHOD, create(METHOD, TaintCommand.INSERT, Collections.singletonList("P1"))); // P2=>O METHOD = "java.lang.StringBuilder.insert(int,java.lang.CharSequence,int,int)"; - put(METHOD, create(METHOD, TaintCommand.INSERT, Arrays.asList("P1", "P3", "P4"))); + put(METHOD, create(METHOD, TaintCommand.INSERT, Arrays.asList("P1", "P3", "P4"))); // P2=>O METHOD = "java.lang.StringBuilder.insert(int,char[],int,int)"; - put(METHOD, create(METHOD, TaintCommand.INSERT, Arrays.asList("P1", "P3", "P4"))); + put(METHOD, create(METHOD, TaintCommand.INSERT, Arrays.asList("P1", "P3", "P4"))); // P2=>O // INSERT StringBuffer METHOD = "java.lang.StringBuffer.insert(int,java.lang.String)"; - put(METHOD, create(METHOD, TaintCommand.INSERT, Collections.singletonList("P1"))); + put(METHOD, create(METHOD, TaintCommand.INSERT, Collections.singletonList("P1"))); // P2=>O METHOD = "java.lang.StringBuffer.insert(int,char[])"; - put(METHOD, create(METHOD, TaintCommand.INSERT, Collections.singletonList("P1"))); + put(METHOD, create(METHOD, TaintCommand.INSERT, Collections.singletonList("P1"))); // P2=>O METHOD = "java.lang.StringBuffer.insert(int,char)"; - put(METHOD, create(METHOD, TaintCommand.INSERT, Collections.singletonList("P1"))); + put(METHOD, create(METHOD, TaintCommand.INSERT, Collections.singletonList("P1"))); // P2=>O METHOD = "java.lang.StringBuffer.insert(int,java.lang.CharSequence)"; - put(METHOD, create(METHOD, TaintCommand.INSERT, Collections.singletonList("P1"))); + put(METHOD, create(METHOD, TaintCommand.INSERT, Collections.singletonList("P1"))); // P2=>O METHOD = "java.lang.StringBuffer.insert(int,java.lang.CharSequence,int,int)"; - put(METHOD, create(METHOD, TaintCommand.INSERT, Arrays.asList("P1", "P3", "P4"))); + put(METHOD, create(METHOD, TaintCommand.INSERT, Arrays.asList("P1", "P3", "P4"))); // P2=>O METHOD = "java.lang.StringBuffer.insert(int,char[],int,int)"; - put(METHOD, create(METHOD, TaintCommand.INSERT, Arrays.asList("P1", "P3", "P4"))); + put(METHOD, create(METHOD, TaintCommand.INSERT, Arrays.asList("P1", "P3", "P4"))); // P2=>O // REMOVE StringBuilder METHOD = "java.lang.StringBuilder.delete(int,int)"; - put(METHOD, create(METHOD, TaintCommand.REMOVE, Arrays.asList("P1", "P2"))); - METHOD = "java.io.StringBuilder.deleteCharAt(int)"; - put(METHOD, create(METHOD, TaintCommand.REMOVE, Collections.singletonList("P1"))); + put(METHOD, create(METHOD, TaintCommand.REMOVE, Arrays.asList("P1", "P2"))); // O=>O + METHOD = "java.lang.StringBuilder.deleteCharAt(int)"; + put(METHOD, create(METHOD, TaintCommand.REMOVE, Collections.singletonList("P1"))); // O=>O // REMOVE StringBuffer METHOD = "java.lang.StringBuffer.delete(int,int)"; - put(METHOD, create(METHOD, TaintCommand.REMOVE, Arrays.asList("P1", "P2"))); - METHOD = "java.io.StringBuffer.deleteCharAt(int)"; - put(METHOD, create(METHOD, TaintCommand.REMOVE, Collections.singletonList("P1"))); + put(METHOD, create(METHOD, TaintCommand.REMOVE, Arrays.asList("P1", "P2"))); // O=>O + METHOD = "java.lang.StringBuffer.deleteCharAt(int)"; + put(METHOD, create(METHOD, TaintCommand.REMOVE, Collections.singletonList("P1"))); // O=>O // REMOVE ByteArrayOutputStream/apache ByteArrayOutputStream METHOD = "java.io.ByteArrayOutputStream.reset()"; - put(METHOD, create(METHOD, TaintCommand.REMOVE)); - METHOD = "org.apache.commons.io.output.ByteArrayOutputStream.reset()"; - put(METHOD, create(METHOD, TaintCommand.REMOVE)); + put(METHOD, create(METHOD, TaintCommand.REMOVE)); // O=>O + METHOD = " org.apache.commons.io.output.ByteArrayOutputStream.reset()".substring(1); + put(METHOD, create(METHOD, TaintCommand.REMOVE)); // O=>O // CONCAT String METHOD = "java.lang.String.concat(java.lang.String)"; - put(METHOD, create(METHOD, TaintCommand.CONCAT)); + put(METHOD, create(METHOD, TaintCommand.CONCAT)); // O|P1=>R // TRIM String - METHOD = "java.lang.String.strip()"; + METHOD = "java.lang.String.strip()"; // Java-11 put(METHOD, create(METHOD, TaintCommand.TRIM)); - METHOD = "java.lang.String.stripLeading()"; + METHOD = "java.lang.String.stripLeading()"; // Java-11 put(METHOD, create(METHOD, TaintCommand.TRIM_LEFT)); - METHOD = "java.lang.String.stripTrailing()"; + METHOD = "java.lang.String.stripTrailing()"; // Java-11 put(METHOD, create(METHOD, TaintCommand.TRIM_RIGHT)); METHOD = "java.lang.String.trim()"; put(METHOD, create(METHOD, TaintCommand.TRIM)); From 03f95c8cf0cf1fe3092557b0a13821bb937dd134 Mon Sep 17 00:00:00 2001 From: lostsnow Date: Thu, 1 Sep 2022 12:20:04 +0800 Subject: [PATCH 16/19] fixes okhttp 2.x/3.x/4.x sink method source taint range --- .../vulscan/dynamic/SSRFSourceCheck.java | 113 +++++++++++++++--- .../taintrange/TaintCommandRunner.java | 12 ++ 2 files changed, 106 insertions(+), 19 deletions(-) diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/SSRFSourceCheck.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/SSRFSourceCheck.java index 97897401c..c3402c6e3 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/SSRFSourceCheck.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/SSRFSourceCheck.java @@ -5,6 +5,8 @@ import io.dongtai.iast.core.utils.TaintPoolUtils; import io.dongtai.log.DongTaiLog; +import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.net.URI; import java.net.URL; import java.util.*; @@ -13,17 +15,29 @@ public class SSRFSourceCheck { private static final String JAVA_NET_URL_OPEN_CONNECTION = "java.net.URL.openConnection()"; private static final String JAVA_NET_URL_OPEN_CONNECTION_PROXY = "java.net.URL.openConnection(java.net.Proxy)"; private static final String JAVA_NET_URL_OPEN_STREAM = "java.net.URL.openStream()"; - // TODO: use method execute for sink private static final String APACHE_HTTP_CLIENT_REQUEST_SET_URI = " org.apache.http.client.methods.HttpRequestBase.setURI(java.net.URI)".substring(1); - private static final String APACHE_LEGACY_HTTP_CLIENT_REQUEST_SET_URI = " org.apache.commons.httpclient.HttpMethodBase.setURI(org.apache.commons.httpclient.HttpMethodBase.URI)".substring(1); + private static final String APACHE_LEGACY_HTTP_CLIENT_REQUEST_SET_URI = " org.apache.commons.httpclient.HttpMethodBase.setURI(org.apache.commons.httpclient.URI)".substring(1); + private static final String OKHTTP3_CALL_EXECUTE = "okhttp3.Call.execute()"; + private static final String OKHTTP3_CALL_ENQUEUE = "okhttp3.Call.enqueue(okhttp3.Callback)"; + private static final String OKHTTP_CALL_EXECUTE = "com.squareup.okhttp.Call.execute()"; + private static final String OKHTTP_CALL_ENQUEUE = "com.squareup.okhttp.Call.enqueue(com.squareup.okhttp.Callback)"; + + private static final String APACHE_LEGACY_HTTP_CLIENT_METHOD_BASE = " org.apache.commons.httpclient.HttpMethodBase".substring(1); + private static final String OKHTTP3_INTERNAL_REAL_CALL = "okhttp3.internal.connection.RealCall"; + private static final String OKHTTP3_REAL_CALL = "okhttp3.RealCall"; + private static final String OKHTTP_CALL = "com.squareup.okhttp.Call"; private static final Set SSRF_SINK_METHODS = new HashSet<>(Arrays.asList( JAVA_NET_URL_OPEN_CONNECTION, JAVA_NET_URL_OPEN_CONNECTION_PROXY, JAVA_NET_URL_OPEN_STREAM, APACHE_HTTP_CLIENT_REQUEST_SET_URI, - APACHE_LEGACY_HTTP_CLIENT_REQUEST_SET_URI + APACHE_LEGACY_HTTP_CLIENT_REQUEST_SET_URI, + OKHTTP3_CALL_EXECUTE, + OKHTTP3_CALL_ENQUEUE, + OKHTTP_CALL_EXECUTE, + OKHTTP_CALL_ENQUEUE )); public static boolean isSinkMethod(IastSinkModel sink) { @@ -39,24 +53,29 @@ public static boolean sourceHitTaintPool(MethodEvent event, IastSinkModel sink) } else if (APACHE_HTTP_CLIENT_REQUEST_SET_URI.equals(sink.getSignature()) || APACHE_LEGACY_HTTP_CLIENT_REQUEST_SET_URI.equals(sink.getSignature())) { return apacheHttpClientRequestSetURISourceHit(event, sink); + } else if (OKHTTP3_CALL_EXECUTE.equals(sink.getSignature()) + || OKHTTP3_CALL_ENQUEUE.equals(sink.getSignature()) + || OKHTTP_CALL_EXECUTE.equals(sink.getSignature()) + || OKHTTP_CALL_ENQUEUE.equals(sink.getSignature())) { + return okhttpSourceHit(event, sink); } return hitTaintPool; } - private static boolean javaNetURLSourceHit(MethodEvent event, IastSinkModel sink) { + private static boolean processJavaNetUrl(MethodEvent event, Object u) { try { - if (!(event.object instanceof URL)) { + if (!(u instanceof URL)) { return false; } - URL url = (URL) event.object; + URL url = (URL) u; String protocol = url.getProtocol(); String userInfo = url.getUserInfo(); String host = url.getHost(); String path = url.getPath(); String query = url.getQuery(); - event.inValue = url.toString(); + event.setInValue(url.toString()); return addSourceType(event, protocol, userInfo, host, path, query); } catch (Exception e) { DongTaiLog.warn("java.net.URL get source failed: " + e.getMessage()); @@ -64,6 +83,31 @@ private static boolean javaNetURLSourceHit(MethodEvent event, IastSinkModel sink } } + private static boolean processJavaNetUri(MethodEvent event, Object u) { + try { + if (!(u instanceof URI)) { + return false; + } + + URI uri = (URI) u; + String protocol = uri.getScheme(); + String userInfo = uri.getUserInfo(); + String host = uri.getHost(); + String path = uri.getPath(); + String query = uri.getQuery(); + + event.setInValue(uri.toString()); + return addSourceType(event, protocol, userInfo, host, path, query); + } catch (Exception e) { + DongTaiLog.warn("java.net.URI get source failed: " + e.getMessage()); + return false; + } + } + + private static boolean javaNetURLSourceHit(MethodEvent event, IastSinkModel sink) { + return processJavaNetUrl(event, event.object); + } + private static boolean apacheHttpClientRequestSetURISourceHit(MethodEvent event, IastSinkModel sink) { try { if (event.argumentArray.length < 1 || event.argumentArray[0] == null) { @@ -72,24 +116,15 @@ private static boolean apacheHttpClientRequestSetURISourceHit(MethodEvent event, Object obj = event.argumentArray[0]; if (event.argumentArray[0] instanceof URI) { - URI uri = (URI) obj; - - String protocol = uri.getScheme(); - String userInfo = uri.getUserInfo(); - String host = uri.getHost(); - String path = uri.getPath(); - String query = uri.getQuery(); - - event.inValue = uri.toString(); - return addSourceType(event, protocol, userInfo, host, path, query); - } else if ("org.apache.commons.httpclient.HttpMethodBase".equals(obj.getClass().getName())) { + return processJavaNetUri(event, obj); + } else if (APACHE_LEGACY_HTTP_CLIENT_METHOD_BASE.equals(obj.getClass().getName())) { String protocol = (String) obj.getClass().getMethod("getScheme").invoke(obj); String userInfo = (String) obj.getClass().getMethod("getUserinfo").invoke(obj); String host = (String) obj.getClass().getMethod("getHost").invoke(obj); String path = (String) obj.getClass().getMethod("getPath").invoke(obj); String query = (String) obj.getClass().getMethod("getQuery").invoke(obj); - event.inValue = (String) obj.getClass().getMethod("toString").invoke(obj); + event.setInValue((String) obj.getClass().getMethod("toString").invoke(obj)); return addSourceType(event, protocol, userInfo, host, path, query); } @@ -100,6 +135,46 @@ private static boolean apacheHttpClientRequestSetURISourceHit(MethodEvent event, } } + private static boolean okhttpSourceHit(MethodEvent event, IastSinkModel sink) { + try { + Class cls = event.object.getClass(); + if (OKHTTP3_REAL_CALL.equals(cls.getName()) || OKHTTP3_INTERNAL_REAL_CALL.equals(cls.getName()) + || OKHTTP_CALL.equals(cls.getName())) { + Object url; + + if (OKHTTP_CALL.equals(cls.getName())) { + Field reqField = cls.getDeclaredField("originalRequest"); + reqField.setAccessible(true); + Object req = reqField.get(event.object); + url = req.getClass().getMethod("httpUrl").invoke(req); + } else { + Method reqMethod = cls.getDeclaredMethod("request"); + reqMethod.setAccessible(true); + Object req = reqMethod.invoke(event.object); + url = req.getClass().getMethod("url").invoke(req); + } + + if (url == null || !url.getClass().getName().endsWith("HttpUrl")) { + return false; + } + + String protocol = (String) url.getClass().getMethod("scheme").invoke(url); + String userInfo = (String) url.getClass().getMethod("username").invoke(url); + String host = (String) url.getClass().getMethod("host").invoke(url); + String path = (String) url.getClass().getMethod("encodedPath").invoke(url); + String query = (String) url.getClass().getMethod("query").invoke(url); + + event.setInValue((String) url.getClass().getMethod("toString").invoke(url)); + return addSourceType(event, protocol, userInfo, host, path, query); + } + + return false; + } catch (Exception e) { + DongTaiLog.warn("okhttp get source failed: " + e.getMessage()); + return false; + } + } + private static boolean addSourceType(MethodEvent event, String protocol, String userInfo, String host, String path, String query) { boolean hit1 = !"".equals(protocol) && TaintPoolUtils.poolContains(protocol, event); boolean hit2 = !"".equals(userInfo) && TaintPoolUtils.poolContains(userInfo, event); diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommandRunner.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommandRunner.java index 5f15f7c34..e12c02e80 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommandRunner.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/taintrange/TaintCommandRunner.java @@ -193,6 +193,10 @@ public static TaintCommandRunner getCommandRunner(String signature) { METHOD = "java.io.StringWriter.toString()"; put(METHOD, create(METHOD, TaintCommand.KEEP)); // O=>R + // KEEP + METHOD = "okhttp3.internal.HostnamesKt.toCanonicalHost(java.lang.String)"; + put(METHOD, create(METHOD, TaintCommand.KEEP)); // P1=>R + // APPEND String METHOD = "java.lang.String.(char[],int,int)"; put(METHOD, create(METHOD, TaintCommand.APPEND, Arrays.asList("P2", "P3", "0"))); // P1=>O @@ -313,6 +317,14 @@ public static TaintCommandRunner getCommandRunner(String signature) { METHOD = "java.util.Arrays.copyOfRange(char[],int,int)"; put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P2", "P3"))); // P1=>R + // SUBSET + METHOD = "okhttp3.HttpUrl$Companion.percentDecode$okhttp(java.lang.String,int,int,boolean)"; + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P2", "P3"))); // P1=>R + METHOD = "okhttp3.HttpUrl$Builder.canonicalizeHost(java.lang.String,int,int)"; + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P2", "P3"))); // P1=>R + METHOD = "com.squareup.okhttp.HttpUrl$Builder.canonicalizeHost(java.lang.String,int,int)"; + put(METHOD, create(METHOD, TaintCommand.SUBSET, Arrays.asList("P2", "P3"))); // P1=>R + // INSERT CharArrayReader/PipedReader/PipedInputStream METHOD = "java.io.CharArrayReader.(char[],int,int)"; put(METHOD, create(METHOD, TaintCommand.INSERT, Arrays.asList("0", "P2", "P3"))); // P1=>O From 8b7e026b9a54370dfc5677663d66d8ef7825c3ed Mon Sep 17 00:00:00 2001 From: lostsnow Date: Thu, 1 Sep 2022 16:16:52 +0800 Subject: [PATCH 17/19] fixes apache legacy http taint source --- .../handler/hookpoint/models/MethodEvent.java | 9 +++++++-- .../vulscan/dynamic/SSRFSourceCheck.java | 18 +++++++++--------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/models/MethodEvent.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/models/MethodEvent.java index a718888e2..4dbe27919 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/models/MethodEvent.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/models/MethodEvent.java @@ -1,6 +1,7 @@ package io.dongtai.iast.core.handler.hookpoint.models; import io.dongtai.iast.core.handler.hookpoint.vulscan.taintrange.TaintRanges; +import io.dongtai.iast.core.handler.hookpoint.vulscan.taintrange.TaintRangesBuilder; import io.dongtai.iast.core.utils.PropertyUtils; import io.dongtai.log.DongTaiLog; import org.json.JSONObject; @@ -323,8 +324,12 @@ public String obj2String(Object value) { return ""; } try { - // 判断是否是基本类型的数组,基本类型的数组无法类型转换为Object[],导致java.lang.ClassCastException异常 - if (value.getClass().isArray() && !value.getClass().getComponentType().isPrimitive()) { + if (value instanceof byte[]) { + return TaintRangesBuilder.trimRight((byte[]) value); + } else if (value instanceof char[]) { + return TaintRangesBuilder.trimRight((char[]) value); + } else if (value.getClass().isArray() && !value.getClass().getComponentType().isPrimitive()) { + // 判断是否是基本类型的数组,基本类型的数组无法类型转换为Object[],导致java.lang.ClassCastException异常 Object[] taints = (Object[]) value; for (Object taint : taints) { if (taint != null) { diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/SSRFSourceCheck.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/SSRFSourceCheck.java index c3402c6e3..f333e3456 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/SSRFSourceCheck.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/SSRFSourceCheck.java @@ -23,7 +23,7 @@ public class SSRFSourceCheck { private static final String OKHTTP_CALL_EXECUTE = "com.squareup.okhttp.Call.execute()"; private static final String OKHTTP_CALL_ENQUEUE = "com.squareup.okhttp.Call.enqueue(com.squareup.okhttp.Callback)"; - private static final String APACHE_LEGACY_HTTP_CLIENT_METHOD_BASE = " org.apache.commons.httpclient.HttpMethodBase".substring(1); + private static final String APACHE_LEGACY_HTTP_CLIENT_URI = " org.apache.commons.httpclient.URI".substring(1); private static final String OKHTTP3_INTERNAL_REAL_CALL = "okhttp3.internal.connection.RealCall"; private static final String OKHTTP3_REAL_CALL = "okhttp3.RealCall"; private static final String OKHTTP_CALL = "com.squareup.okhttp.Call"; @@ -115,14 +115,14 @@ private static boolean apacheHttpClientRequestSetURISourceHit(MethodEvent event, } Object obj = event.argumentArray[0]; - if (event.argumentArray[0] instanceof URI) { + if (obj instanceof URI) { return processJavaNetUri(event, obj); - } else if (APACHE_LEGACY_HTTP_CLIENT_METHOD_BASE.equals(obj.getClass().getName())) { - String protocol = (String) obj.getClass().getMethod("getScheme").invoke(obj); - String userInfo = (String) obj.getClass().getMethod("getUserinfo").invoke(obj); - String host = (String) obj.getClass().getMethod("getHost").invoke(obj); - String path = (String) obj.getClass().getMethod("getPath").invoke(obj); - String query = (String) obj.getClass().getMethod("getQuery").invoke(obj); + } else if (APACHE_LEGACY_HTTP_CLIENT_URI.equals(obj.getClass().getName())) { + Object protocol = obj.getClass().getMethod("getRawScheme").invoke(obj); + Object userInfo = obj.getClass().getMethod("getRawUserinfo").invoke(obj); + Object host = obj.getClass().getMethod("getRawHost").invoke(obj); + Object path = obj.getClass().getMethod("getRawPath").invoke(obj); + Object query = obj.getClass().getMethod("getRawQuery").invoke(obj); event.setInValue((String) obj.getClass().getMethod("toString").invoke(obj)); return addSourceType(event, protocol, userInfo, host, path, query); @@ -175,7 +175,7 @@ private static boolean okhttpSourceHit(MethodEvent event, IastSinkModel sink) { } } - private static boolean addSourceType(MethodEvent event, String protocol, String userInfo, String host, String path, String query) { + private static boolean addSourceType(MethodEvent event, Object protocol, Object userInfo, Object host, Object path, Object query) { boolean hit1 = !"".equals(protocol) && TaintPoolUtils.poolContains(protocol, event); boolean hit2 = !"".equals(userInfo) && TaintPoolUtils.poolContains(userInfo, event); boolean hit3 = !"".equals(host) && TaintPoolUtils.poolContains(host, event); From 13412caab3173653d27ed5d9b9a87b3117670082 Mon Sep 17 00:00:00 2001 From: lostsnow Date: Thu, 1 Sep 2022 18:09:44 +0800 Subject: [PATCH 18/19] fixes apache httpclient5 taint source --- .../vulscan/dynamic/SSRFSourceCheck.java | 132 +++++++++++------- 1 file changed, 82 insertions(+), 50 deletions(-) diff --git a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/SSRFSourceCheck.java b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/SSRFSourceCheck.java index f333e3456..1bdb776ab 100644 --- a/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/SSRFSourceCheck.java +++ b/dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/SSRFSourceCheck.java @@ -18,12 +18,14 @@ public class SSRFSourceCheck { // TODO: use method execute for sink private static final String APACHE_HTTP_CLIENT_REQUEST_SET_URI = " org.apache.http.client.methods.HttpRequestBase.setURI(java.net.URI)".substring(1); private static final String APACHE_LEGACY_HTTP_CLIENT_REQUEST_SET_URI = " org.apache.commons.httpclient.HttpMethodBase.setURI(org.apache.commons.httpclient.URI)".substring(1); + private static final String APACHE_HTTP_CLIENT5_EXECUTE = " org.apache.hc.client5.http.impl.classic.CloseableHttpClient.doExecute(org.apache.hc.core5.http.HttpHost,org.apache.hc.core5.http.ClassicHttpRequest,org.apache.hc.core5.http.protocol.HttpContext)".substring(1); private static final String OKHTTP3_CALL_EXECUTE = "okhttp3.Call.execute()"; private static final String OKHTTP3_CALL_ENQUEUE = "okhttp3.Call.enqueue(okhttp3.Callback)"; private static final String OKHTTP_CALL_EXECUTE = "com.squareup.okhttp.Call.execute()"; private static final String OKHTTP_CALL_ENQUEUE = "com.squareup.okhttp.Call.enqueue(com.squareup.okhttp.Callback)"; private static final String APACHE_LEGACY_HTTP_CLIENT_URI = " org.apache.commons.httpclient.URI".substring(1); + private static final String APACHE_HTTP_CLIENT5_HTTP_REQUEST = " org.apache.hc.client5.http.classic.methods.HttpUriRequestBase".substring(1); private static final String OKHTTP3_INTERNAL_REAL_CALL = "okhttp3.internal.connection.RealCall"; private static final String OKHTTP3_REAL_CALL = "okhttp3.RealCall"; private static final String OKHTTP_CALL = "com.squareup.okhttp.Call"; @@ -34,6 +36,7 @@ public class SSRFSourceCheck { JAVA_NET_URL_OPEN_STREAM, APACHE_HTTP_CLIENT_REQUEST_SET_URI, APACHE_LEGACY_HTTP_CLIENT_REQUEST_SET_URI, + APACHE_HTTP_CLIENT5_EXECUTE, OKHTTP3_CALL_EXECUTE, OKHTTP3_CALL_ENQUEUE, OKHTTP_CALL_EXECUTE, @@ -52,7 +55,9 @@ public static boolean sourceHitTaintPool(MethodEvent event, IastSinkModel sink) return javaNetURLSourceHit(event, sink); } else if (APACHE_HTTP_CLIENT_REQUEST_SET_URI.equals(sink.getSignature()) || APACHE_LEGACY_HTTP_CLIENT_REQUEST_SET_URI.equals(sink.getSignature())) { - return apacheHttpClientRequestSetURISourceHit(event, sink); + return apacheHttpClientSourceHit(event, sink); + } else if (APACHE_HTTP_CLIENT5_EXECUTE.equals(sink.getSignature())) { + return apacheHttpClient5SourceHit(event, sink); } else if (OKHTTP3_CALL_EXECUTE.equals(sink.getSignature()) || OKHTTP3_CALL_ENQUEUE.equals(sink.getSignature()) || OKHTTP_CALL_EXECUTE.equals(sink.getSignature()) @@ -69,14 +74,16 @@ private static boolean processJavaNetUrl(MethodEvent event, Object u) { } URL url = (URL) u; - String protocol = url.getProtocol(); - String userInfo = url.getUserInfo(); - String host = url.getHost(); - String path = url.getPath(); - String query = url.getQuery(); + Map sourceMap = new HashMap() {{ + put("PROTOCOL", url.getProtocol()); + put("USERINFO", url.getUserInfo()); + put("HOST", url.getHost()); + put("PATH", url.getPath()); + put("QUERY", url.getQuery()); + }}; event.setInValue(url.toString()); - return addSourceType(event, protocol, userInfo, host, path, query); + return addSourceType(event, sourceMap); } catch (Exception e) { DongTaiLog.warn("java.net.URL get source failed: " + e.getMessage()); return false; @@ -90,14 +97,16 @@ private static boolean processJavaNetUri(MethodEvent event, Object u) { } URI uri = (URI) u; - String protocol = uri.getScheme(); - String userInfo = uri.getUserInfo(); - String host = uri.getHost(); - String path = uri.getPath(); - String query = uri.getQuery(); + Map sourceMap = new HashMap() {{ + put("PROTOCOL", uri.getScheme()); + put("USERINFO", uri.getUserInfo()); + put("HOST", uri.getHost()); + put("PATH", uri.getPath()); + put("QUERY", uri.getQuery()); + }}; event.setInValue(uri.toString()); - return addSourceType(event, protocol, userInfo, host, path, query); + return addSourceType(event, sourceMap); } catch (Exception e) { DongTaiLog.warn("java.net.URI get source failed: " + e.getMessage()); return false; @@ -108,7 +117,7 @@ private static boolean javaNetURLSourceHit(MethodEvent event, IastSinkModel sink return processJavaNetUrl(event, event.object); } - private static boolean apacheHttpClientRequestSetURISourceHit(MethodEvent event, IastSinkModel sink) { + private static boolean apacheHttpClientSourceHit(MethodEvent event, IastSinkModel sink) { try { if (event.argumentArray.length < 1 || event.argumentArray[0] == null) { return false; @@ -118,14 +127,16 @@ private static boolean apacheHttpClientRequestSetURISourceHit(MethodEvent event, if (obj instanceof URI) { return processJavaNetUri(event, obj); } else if (APACHE_LEGACY_HTTP_CLIENT_URI.equals(obj.getClass().getName())) { - Object protocol = obj.getClass().getMethod("getRawScheme").invoke(obj); - Object userInfo = obj.getClass().getMethod("getRawUserinfo").invoke(obj); - Object host = obj.getClass().getMethod("getRawHost").invoke(obj); - Object path = obj.getClass().getMethod("getRawPath").invoke(obj); - Object query = obj.getClass().getMethod("getRawQuery").invoke(obj); + Map sourceMap = new HashMap() {{ + put("PROTOCOL", obj.getClass().getMethod("getRawScheme").invoke(obj)); + put("USERINFO", obj.getClass().getMethod("getRawUserinfo").invoke(obj)); + put("HOST", obj.getClass().getMethod("getRawHost").invoke(obj)); + put("PATH", obj.getClass().getMethod("getRawPath").invoke(obj)); + put("QUERY", obj.getClass().getMethod("getRawQuery").invoke(obj)); + }}; event.setInValue((String) obj.getClass().getMethod("toString").invoke(obj)); - return addSourceType(event, protocol, userInfo, host, path, query); + return addSourceType(event, sourceMap); } return false; @@ -135,6 +146,36 @@ private static boolean apacheHttpClientRequestSetURISourceHit(MethodEvent event, } } + private static boolean apacheHttpClient5SourceHit(MethodEvent event, IastSinkModel sink) { + try { + if (event.argumentArray.length < 2 || event.argumentArray[1] == null) { + return false; + } + + Object reqObj = event.argumentArray[1]; + if (APACHE_HTTP_CLIENT5_HTTP_REQUEST.equals(reqObj.getClass().getName()) + || APACHE_HTTP_CLIENT5_HTTP_REQUEST.equals(reqObj.getClass().getSuperclass().getName())) { + Object authorityObj = reqObj.getClass().getMethod("getAuthority").invoke(reqObj); + Map sourceMap = new HashMap() {{ + put("PROTOCOL", reqObj.getClass().getMethod("getScheme").invoke(reqObj)); + put("USERINFO", authorityObj.getClass().getMethod("getUserInfo").invoke(authorityObj)); + put("HOST", authorityObj.getClass().getMethod("getHostName").invoke(authorityObj)); + // getPath = path + query + put("PATHQUERY", reqObj.getClass().getMethod("getPath").invoke(reqObj)); + }}; + + Object uriObj = reqObj.getClass().getMethod("getUri").invoke(reqObj); + event.setInValue((String) uriObj.getClass().getMethod("toString").invoke(uriObj)); + return addSourceType(event, sourceMap); + } + + return false; + } catch (Exception e) { + DongTaiLog.warn("apache http client5 get source failed: " + e.getMessage()); + return false; + } + } + private static boolean okhttpSourceHit(MethodEvent event, IastSinkModel sink) { try { Class cls = event.object.getClass(); @@ -158,14 +199,17 @@ private static boolean okhttpSourceHit(MethodEvent event, IastSinkModel sink) { return false; } - String protocol = (String) url.getClass().getMethod("scheme").invoke(url); - String userInfo = (String) url.getClass().getMethod("username").invoke(url); - String host = (String) url.getClass().getMethod("host").invoke(url); - String path = (String) url.getClass().getMethod("encodedPath").invoke(url); - String query = (String) url.getClass().getMethod("query").invoke(url); + Map sourceMap = new HashMap() {{ + put("PROTOCOL", url.getClass().getMethod("scheme").invoke(url)); + put("USERNAME", url.getClass().getMethod("username").invoke(url)); + put("PASSWORD", url.getClass().getMethod("password").invoke(url)); + put("HOST", url.getClass().getMethod("host").invoke(url)); + put("PATH", url.getClass().getMethod("encodedPath").invoke(url)); + put("QUERY", url.getClass().getMethod("query").invoke(url)); + }}; event.setInValue((String) url.getClass().getMethod("toString").invoke(url)); - return addSourceType(event, protocol, userInfo, host, path, query); + return addSourceType(event, sourceMap); } return false; @@ -175,32 +219,20 @@ private static boolean okhttpSourceHit(MethodEvent event, IastSinkModel sink) { } } - private static boolean addSourceType(MethodEvent event, Object protocol, Object userInfo, Object host, Object path, Object query) { - boolean hit1 = !"".equals(protocol) && TaintPoolUtils.poolContains(protocol, event); - boolean hit2 = !"".equals(userInfo) && TaintPoolUtils.poolContains(userInfo, event); - boolean hit3 = !"".equals(host) && TaintPoolUtils.poolContains(host, event); - boolean hit4 = !"".equals(path) && TaintPoolUtils.poolContains(path, event); - boolean hit5 = !"".equals(query) && TaintPoolUtils.poolContains(query, event); - event.inValue = event.object.toString(); - boolean hit = hit1 || hit2 || hit3 || hit4 || hit5; - if (hit && event.sourceTypes == null) { - event.sourceTypes = new ArrayList(); - if (hit1) { - event.sourceTypes.add(new MethodEvent.MethodEventSourceType(System.identityHashCode(protocol), "PROTOCOL")); - } - if (hit2) { - event.sourceTypes.add(new MethodEvent.MethodEventSourceType(System.identityHashCode(userInfo), "USERINFO")); - } - if (hit3) { - event.sourceTypes.add(new MethodEvent.MethodEventSourceType(System.identityHashCode(host), "HOST")); - } - if (hit4) { - event.sourceTypes.add(new MethodEvent.MethodEventSourceType(System.identityHashCode(path), "PATH")); - } - if (hit5) { - event.sourceTypes.add(new MethodEvent.MethodEventSourceType(System.identityHashCode(query), "QUERY")); + private static boolean addSourceType(MethodEvent event, Map sourceMap) { + boolean hit = false; + event.sourceTypes = new ArrayList(); + for (Map.Entry entry : sourceMap.entrySet()) { + if (!"".equals(entry.getValue()) && TaintPoolUtils.poolContains(entry.getValue(), event)) { + event.sourceTypes.add(new MethodEvent.MethodEventSourceType(System.identityHashCode(entry.getValue()), entry.getKey())); + hit = true; } } + + if (event.sourceTypes.size() == 0) { + event.sourceTypes = null; + } + return hit; } } From f2b23222c12ee8ce2523f8b72c9ed350662ee9a5 Mon Sep 17 00:00:00 2001 From: lostsnow Date: Fri, 2 Sep 2022 17:38:00 +0800 Subject: [PATCH 19/19] fixes propagator empty target taint range --- .../handler/hookpoint/controller/impl/PropagatorImpl.java | 4 ++++ 1 file changed, 4 insertions(+) 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 6a8921e7b..8443cddb8 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 @@ -230,6 +230,10 @@ private static void trackTaintRange(IastPropagatorModel propagator, MethodEvent return; } + if (!TaintPoolUtils.isNotEmpty(tgt)) { + return; + } + TaintRanges tr; if (r != null && srcValue != null) { tr = r.run(srcValue, tgtValue, event.argumentArray, oldTaintRanges, srcTaintRanges);