Skip to content

Commit 1142b32

Browse files
authored
Merge pull request #531 from lostsnow/feature/add-sink-taint-tag-check
add sink taint tag check
2 parents bce3f0d + 13868b4 commit 1142b32

File tree

4 files changed

+81
-20
lines changed

4 files changed

+81
-20
lines changed

dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/models/taint/range/TaintRanges.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ public void untag(String[] untags) {
5858
}
5959

6060
public boolean hasRequiredTaintTags(TaintTag[] tags) {
61+
if (tags == null) {
62+
return true;
63+
}
6164
int total = tags.length;
6265
Map<String, Boolean> found = new HashMap<String, Boolean>();
6366
for (TaintTag tag : tags) {
@@ -71,6 +74,9 @@ public boolean hasRequiredTaintTags(TaintTag[] tags) {
7174
}
7275

7376
public boolean hasDisallowedTaintTags(TaintTag[] tags) {
77+
if (tags == null) {
78+
return false;
79+
}
7480
for (TaintTag tag : tags) {
7581
for (TaintRange taintRange : this.taintRanges) {
7682
if (tag.equals(taintRange.getName())) {

dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/models/taint/tag/TaintTag.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,13 @@ public enum TaintTag {
2727
FTL_DECODED("ftl-decoded"),
2828
CSS_ENCODED("css-encoded"),
2929
XPATH_ENCODED("xpath-encoded"),
30+
XPATH_DECODED("xpath-decoded"),
3031
LDAP_ENCODED("ldap-encoded"),
32+
LDAP_DECODED("ldap-decoded"),
3133
OS_ENCODED("os-encoded"),
3234
VBSCRIPT_ENCODED("vbscript-encoded"),
35+
HTTP_TOKEN_LIMITED_CHARS("http-token-limited-chars"),
36+
NUMERIC_LIMITED_CHARS("numeric-limited-chars"),
3337
;
3438

3539
private final String key;

dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/VulnType.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@ public enum VulnType {
1515
CRYPTO_BAD_MAC("crypto-bad-mac", "high", false),
1616
COOKIE_FLAGS_MISSING("cookie-flags-missing", "high", true),
1717
REFLECTED_XSS("reflected-xss", "medium", true),
18+
SQL_INJECTION("sql-injection", "high", true),
19+
HQL_INJECTION("hql-injection", "high", true),
20+
LDAP_INJECTION("ldap-injection", "high", true),
21+
CMD_INJECTION("cmd-injection", "high", true),
22+
XPATH_INJECTION("xpath-injection", "high", true),
23+
PATH_TRAVERSAL("path-traversal", "high", true),
24+
XXE("xxe", "medium", true),
25+
UNVALIDATED_REDIRECT("unvalidated-redirect", "low", true),
1826
;
1927

2028
public String getName() {

dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/vulscan/dynamic/DynamicPropagatorScanner.java

Lines changed: 63 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,50 @@ public class DynamicPropagatorScanner implements IVulScan {
3636
new HttpService()
3737
));
3838

39+
// VulnType => List<TAGS, UNTAGS>
40+
private static final Map<String, List<TaintTag[]>> TAINT_TAG_CHECKS = new HashMap<String, List<TaintTag[]>>() {{
41+
put(VulnType.REFLECTED_XSS.getName(), Arrays.asList(
42+
new TaintTag[]{TaintTag.UNTRUSTED, TaintTag.CROSS_SITE},
43+
new TaintTag[]{TaintTag.BASE64_ENCODED, TaintTag.HTML_ENCODED, TaintTag.LDAP_ENCODED,
44+
TaintTag.SQL_ENCODED, TaintTag.URL_ENCODED, TaintTag.XML_ENCODED, TaintTag.XPATH_ENCODED,
45+
TaintTag.XSS_ENCODED, TaintTag.HTTP_TOKEN_LIMITED_CHARS, TaintTag.NUMERIC_LIMITED_CHARS}
46+
));
47+
put(VulnType.SQL_INJECTION.getName(), Arrays.asList(
48+
new TaintTag[]{TaintTag.UNTRUSTED},
49+
new TaintTag[]{TaintTag.SQL_ENCODED, TaintTag.HTTP_TOKEN_LIMITED_CHARS, TaintTag.NUMERIC_LIMITED_CHARS}
50+
));
51+
put(VulnType.HQL_INJECTION.getName(), Arrays.asList(
52+
new TaintTag[]{TaintTag.UNTRUSTED},
53+
new TaintTag[]{TaintTag.SQL_ENCODED, TaintTag.HTTP_TOKEN_LIMITED_CHARS, TaintTag.NUMERIC_LIMITED_CHARS}
54+
));
55+
put(VulnType.LDAP_INJECTION.getName(), Arrays.asList(
56+
new TaintTag[]{TaintTag.UNTRUSTED},
57+
new TaintTag[]{TaintTag.BASE64_ENCODED, TaintTag.HTML_ENCODED, TaintTag.LDAP_ENCODED,
58+
TaintTag.SQL_ENCODED, TaintTag.URL_ENCODED, TaintTag.XML_ENCODED, TaintTag.XPATH_ENCODED,
59+
TaintTag.HTTP_TOKEN_LIMITED_CHARS, TaintTag.NUMERIC_LIMITED_CHARS}
60+
));
61+
put(VulnType.XPATH_INJECTION.getName(), Arrays.asList(
62+
new TaintTag[]{TaintTag.UNTRUSTED},
63+
new TaintTag[]{TaintTag.XML_ENCODED, TaintTag.HTTP_TOKEN_LIMITED_CHARS, TaintTag.NUMERIC_LIMITED_CHARS}
64+
));
65+
put(VulnType.CMD_INJECTION.getName(), Arrays.asList(
66+
new TaintTag[]{TaintTag.UNTRUSTED},
67+
new TaintTag[]{TaintTag.BASE64_ENCODED, TaintTag.HTML_ENCODED, TaintTag.LDAP_ENCODED,
68+
TaintTag.SQL_ENCODED, TaintTag.URL_ENCODED, TaintTag.XML_ENCODED, TaintTag.XPATH_ENCODED,
69+
TaintTag.HTTP_TOKEN_LIMITED_CHARS, TaintTag.NUMERIC_LIMITED_CHARS}
70+
));
71+
put(VulnType.PATH_TRAVERSAL.getName(), Arrays.asList(
72+
new TaintTag[]{TaintTag.UNTRUSTED},
73+
new TaintTag[]{TaintTag.BASE64_ENCODED, TaintTag.HTML_ENCODED, TaintTag.LDAP_ENCODED,
74+
TaintTag.URL_ENCODED, TaintTag.XML_ENCODED, TaintTag.XPATH_ENCODED,
75+
TaintTag.HTTP_TOKEN_LIMITED_CHARS, TaintTag.NUMERIC_LIMITED_CHARS}
76+
));
77+
put(VulnType.UNVALIDATED_REDIRECT.getName(), Arrays.asList(
78+
new TaintTag[]{TaintTag.UNTRUSTED},
79+
new TaintTag[]{TaintTag.URL_ENCODED, TaintTag.HTTP_TOKEN_LIMITED_CHARS, TaintTag.NUMERIC_LIMITED_CHARS}
80+
));
81+
}};
82+
3983
@Override
4084
public void scan(MethodEvent event, SinkNode sinkNode) {
4185
for (SinkSafeChecker chk : SAFE_CHECKERS) {
@@ -118,29 +162,28 @@ private boolean sinkSourceHitTaintPool(MethodEvent event, SinkNode sinkNode) {
118162
}
119163

120164

121-
// TODO: check taint tags at server
122-
if (VulnType.REFLECTED_XSS.equals(sinkNode.getVulType()) && !sourceInstances.isEmpty()) {
123-
boolean tagsHit = false;
124-
for (Object sourceInstance : sourceInstances) {
125-
long hash = TaintPoolUtils.getStringHash(sourceInstance);
126-
TaintRanges tr = EngineManager.TAINT_RANGES_POOL.get(hash);
127-
if (tr == null || tr.isEmpty()) {
128-
continue;
165+
if (!sourceInstances.isEmpty()) {
166+
List<TaintTag[]> tagList = TAINT_TAG_CHECKS.get(sinkNode.getVulType());
167+
if (tagList != null) {
168+
boolean tagsHit = false;
169+
TaintTag[] required = tagList.get(0);
170+
TaintTag[] disallowed = tagList.get(1);
171+
172+
for (Object sourceInstance : sourceInstances) {
173+
long hash = TaintPoolUtils.getStringHash(sourceInstance);
174+
TaintRanges tr = EngineManager.TAINT_RANGES_POOL.get(hash);
175+
if (tr == null || tr.isEmpty()) {
176+
continue;
177+
}
178+
179+
if (tr.hasRequiredTaintTags(required) && !tr.hasDisallowedTaintTags(disallowed)) {
180+
tagsHit = true;
181+
}
129182
}
130-
TaintTag[] required = new TaintTag[]{
131-
TaintTag.UNTRUSTED, TaintTag.CROSS_SITE
132-
};
133-
TaintTag[] disallowed = new TaintTag[]{
134-
TaintTag.XSS_ENCODED, TaintTag.URL_ENCODED,
135-
TaintTag.HTML_ENCODED, TaintTag.BASE64_ENCODED
136-
};
137-
if (tr.hasRequiredTaintTags(required) && !tr.hasDisallowedTaintTags(disallowed)) {
138-
tagsHit = true;
183+
if (!tagsHit) {
184+
return false;
139185
}
140186
}
141-
if (!tagsHit) {
142-
return false;
143-
}
144187
}
145188

146189
if (hasTaint) {

0 commit comments

Comments
 (0)