Skip to content

Commit c7e4a55

Browse files
authored
Merge pull request #502 from HXSecurity/beta
release v1.9.2-beta2
2 parents a175137 + 87a88f2 commit c7e4a55

File tree

30 files changed

+439
-164
lines changed

30 files changed

+439
-164
lines changed

dongtai-agent/src/main/java/io/dongtai/iast/agent/monitor/impl/AgentStateMonitor.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ public void check() {
4343
}
4444

4545
if (this.engineManager.getAgentState().isUninstalledByCli()) {
46+
HttpClientUtils.sendPost(ApiPath.ACTUAL_ACTION,
47+
HeartBeatReport.generateAgentActualActionMsg(this.engineManager.getAgentState()));
4648
return;
4749
}
4850

dongtai-agent/src/main/java/io/dongtai/iast/agent/monitor/impl/ConfigMonitor.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import io.dongtai.iast.agent.util.HttpClientUtils;
77
import io.dongtai.iast.agent.util.ThreadUtils;
88
import io.dongtai.iast.common.config.ConfigBuilder;
9+
import io.dongtai.iast.common.config.ConfigKey;
910
import io.dongtai.iast.common.constants.AgentConstant;
1011
import io.dongtai.iast.common.constants.ApiPath;
1112
import io.dongtai.log.DongTaiLog;
@@ -30,11 +31,25 @@ public void check() {
3031

3132
StringBuilder response = HttpClientUtils.sendGet(ApiPath.AGENT_CONFIG, parameters);
3233
ConfigBuilder.getInstance().updateFromRemote(response.toString());
34+
35+
updateConfig();
3336
} catch (Throwable t) {
3437
DongTaiLog.warn(ErrorCode.AGENT_MONITOR_THREAD_CHECK_FAILED, t);
3538
}
3639
}
3740

41+
private void updateConfig() {
42+
Boolean enableLog = ConfigBuilder.getInstance().get(ConfigKey.ENABLE_LOGGER);
43+
if (enableLog != null) {
44+
DongTaiLog.ENABLED = enableLog;
45+
}
46+
47+
String logLevel = ConfigBuilder.getInstance().get(ConfigKey.LOGGER_LEVEL);
48+
if (logLevel != null) {
49+
DongTaiLog.setLevel(DongTaiLog.parseLevel(logLevel));
50+
}
51+
}
52+
3853
@Override
3954
public void run() {
4055
try {

dongtai-common/src/main/java/io/dongtai/iast/common/config/ConfigBuilder.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,15 @@ private ConfigBuilder() {
1515
this.configMap.put(ConfigKey.REPORT_RESPONSE_BODY,
1616
Config.<Boolean>create(ConfigKey.REPORT_RESPONSE_BODY).setDefaultValue(true));
1717
this.configMap.put(ConfigKey.REQUEST_DENY_LIST,
18-
Config.<RequestDenyList>create(ConfigKey.REQUEST_DENY_LIST).setDefaultValue(null));
18+
Config.<RequestDenyList>create(ConfigKey.REQUEST_DENY_LIST));
1919
this.configMap.put(ConfigKey.ENABLE_VERSION_HEADER,
2020
Config.<Boolean>create(ConfigKey.VERSION_HEADER_KEY).setDefaultValue(true));
2121
this.configMap.put(ConfigKey.VERSION_HEADER_KEY,
2222
Config.<String>create(ConfigKey.VERSION_HEADER_KEY).setDefaultValue("DongTai"));
23+
this.configMap.put(ConfigKey.ENABLE_LOGGER,
24+
Config.<Boolean>create(ConfigKey.ENABLE_LOGGER));
25+
this.configMap.put(ConfigKey.LOGGER_LEVEL,
26+
Config.<String>create(ConfigKey.LOGGER_LEVEL));
2327
}
2428

2529
public static ConfigBuilder getInstance() {
@@ -56,9 +60,20 @@ public void update(JSONObject config) {
5660
updateInt(config, ConfigKey.JsonKey.JSON_REPORT_MAX_METHOD_POOL_SIZE);
5761
updateBool(config, ConfigKey.JsonKey.JSON_ENABLE_VERSION_HEADER);
5862
updateString(config, ConfigKey.JsonKey.JSON_VERSION_HEADER_KEY);
63+
updateBool(config, ConfigKey.JsonKey.JSON_ENABLE_LOGGER);
64+
updateString(config, ConfigKey.JsonKey.JSON_LOGGER_LEVEL);
5965
updateRequestDenyList(config);
6066
}
6167

68+
@SuppressWarnings("unchecked")
69+
public <T> T get(ConfigKey key) {
70+
try {
71+
return ((Config<T>) getConfig(key)).get();
72+
} catch (Throwable ignore) {
73+
return null;
74+
}
75+
}
76+
6277
@SuppressWarnings("unchecked")
6378
private void updateBool(JSONObject config, ConfigKey.JsonKey jsonKey) {
6479
try {
@@ -89,7 +104,7 @@ private void updateString(JSONObject config, ConfigKey.JsonKey jsonKey) {
89104
Config<String> conf = (Config<String>) getConfig(jsonKey.getConfigKey());
90105
if (conf != null) {
91106
String value = config.getString(jsonKey.getKey());
92-
if (value != null || !value.isEmpty()) {
107+
if (value != null && !value.isEmpty()) {
93108
conf.setValue(value);
94109
}
95110
}

dongtai-common/src/main/java/io/dongtai/iast/common/config/ConfigKey.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ public enum ConfigKey {
66
REQUEST_DENY_LIST,
77
ENABLE_VERSION_HEADER,
88
VERSION_HEADER_KEY,
9+
ENABLE_LOGGER,
10+
LOGGER_LEVEL,
911
;
1012

1113
public enum JsonKey {
@@ -14,6 +16,8 @@ public enum JsonKey {
1416
JSON_REQUEST_DENY_LIST("blacklist_rules", REQUEST_DENY_LIST),
1517
JSON_ENABLE_VERSION_HEADER("enable_version_header", ENABLE_VERSION_HEADER),
1618
JSON_VERSION_HEADER_KEY("version_header_name", VERSION_HEADER_KEY),
19+
JSON_ENABLE_LOGGER("enable_log", ENABLE_LOGGER),
20+
JSON_LOGGER_LEVEL("log_level", LOGGER_LEVEL),
1721
;
1822

1923
private final String key;

dongtai-common/src/main/java/io/dongtai/iast/common/constants/AgentConstant.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package io.dongtai.iast.common.constants;
22

33
public class AgentConstant {
4-
public static final String VERSION_VALUE = "v1.9.0-beta1";
4+
public static final String VERSION_VALUE = "v1.9.0-beta2";
55
public static final String LANGUAGE = "JAVA";
66
public static final String THREAD_NAME_PREFIX = "DongTai-IAST-";
77
public static final String THREAD_NAME_PREFIX_CORE = "DongTai-IAST-Core-";

dongtai-common/src/main/java/io/dongtai/iast/common/scope/PolicyScope.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ public class PolicyScope {
66
private int propagatorLevel;
77
private int propagatorSkipDepth;
88
private int sinkLevel;
9+
private int ignoreInternalLevel;
910
/**
1011
* over max method pool size
1112
*/
@@ -29,7 +30,8 @@ public void enterSource() {
2930
}
3031

3132
public boolean isValidSource() {
32-
return this.agentLevel == 0 && !this.overCapacity
33+
return this.agentLevel == 0
34+
&& this.ignoreInternalLevel == 0 && !this.overCapacity
3335
&& this.sourceLevel == 1;
3436
}
3537

@@ -45,7 +47,8 @@ public void enterPropagator(boolean skipScope) {
4547
}
4648

4749
public boolean isValidPropagator() {
48-
return this.agentLevel == 0 && !this.overCapacity && this.sourceLevel == 0
50+
return this.agentLevel == 0
51+
&& this.ignoreInternalLevel == 0 && !this.overCapacity && this.sourceLevel == 0
4952
&& (this.propagatorLevel == 1 || this.propagatorSkipDepth > 0);
5053
}
5154

@@ -61,14 +64,23 @@ public void enterSink() {
6164
}
6265

6366
public boolean isValidSink() {
64-
return this.agentLevel == 0 && !this.overCapacity && this.sourceLevel == 0
67+
return this.agentLevel == 0
68+
&& this.ignoreInternalLevel == 0 && !this.overCapacity && this.sourceLevel == 0
6569
&& this.sinkLevel == 1;
6670
}
6771

6872
public void leaveSink() {
6973
this.sinkLevel = decrement(this.sinkLevel);
7074
}
7175

76+
public void enterIgnoreInternal() {
77+
this.ignoreInternalLevel++;
78+
}
79+
80+
public void leaveIgnoreInternal() {
81+
this.ignoreInternalLevel = decrement(this.ignoreInternalLevel);
82+
}
83+
7284
public boolean isOverCapacity() {
7385
return this.overCapacity;
7486
}

dongtai-common/src/test/java/io/dongtai/iast/common/config/ConfigBuilderTest.java

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,19 @@ public void testGetConfigAndUpdate() {
1313
JSONObject configJson;
1414
String configString;
1515
ConfigBuilder builder = ConfigBuilder.getInstance();
16-
boolean reportResponseBody;
17-
int reportMaxMethodPoolSize;
16+
Boolean reportResponseBody;
17+
Integer reportMaxMethodPoolSize;
18+
String versionHeaderKey;
1819
RequestDenyList requestDenyList;
1920

2021
// default
21-
reportResponseBody = ((Config<Boolean>)builder.getConfig(ConfigKey.REPORT_RESPONSE_BODY)).get();
22+
reportResponseBody = builder.get(ConfigKey.REPORT_RESPONSE_BODY);
2223
Assert.assertTrue("REPORT_RESPONSE_BODY default", reportResponseBody);
23-
reportMaxMethodPoolSize = ((Config<Integer>)builder.getConfig(ConfigKey.REPORT_MAX_METHOD_POOL_SIZE)).get();
24-
Assert.assertEquals("REPORT_MAX_METHOD_POOL_SIZE default", 5000, reportMaxMethodPoolSize);
25-
requestDenyList = ((Config<RequestDenyList>)builder.getConfig(ConfigKey.REQUEST_DENY_LIST)).get();
24+
reportMaxMethodPoolSize = builder.get(ConfigKey.REPORT_MAX_METHOD_POOL_SIZE);
25+
Assert.assertEquals("REPORT_MAX_METHOD_POOL_SIZE default", new Integer(5000), reportMaxMethodPoolSize);
26+
versionHeaderKey = builder.get(ConfigKey.VERSION_HEADER_KEY);
27+
Assert.assertEquals("VERSION_HEADER_KEY default", "DongTai", versionHeaderKey);
28+
requestDenyList = builder.get(ConfigKey.REQUEST_DENY_LIST);
2629
Assert.assertNull("REQUEST_DENY_LIST default", requestDenyList);
2730

2831
// update
@@ -41,11 +44,11 @@ public void testGetConfigAndUpdate() {
4144
RequestDeny.Operator.EXISTS, "key1");
4245
expectRequestDenyList.addRule(Collections.singletonList(headerKeyMatch));
4346

44-
reportResponseBody = ((Config<Boolean>)builder.getConfig(ConfigKey.REPORT_RESPONSE_BODY)).get();
47+
reportResponseBody = builder.get(ConfigKey.REPORT_RESPONSE_BODY);
4548
Assert.assertFalse("REPORT_RESPONSE_BODY updated", reportResponseBody);
46-
reportMaxMethodPoolSize = ((Config<Integer>)builder.getConfig(ConfigKey.REPORT_MAX_METHOD_POOL_SIZE)).get();
47-
Assert.assertEquals("REPORT_MAX_METHOD_POOL_SIZE updated", 1000, reportMaxMethodPoolSize);
48-
requestDenyList = ((Config<RequestDenyList>)builder.getConfig(ConfigKey.REQUEST_DENY_LIST)).get();
49+
reportMaxMethodPoolSize = builder.get(ConfigKey.REPORT_MAX_METHOD_POOL_SIZE);
50+
Assert.assertEquals("REPORT_MAX_METHOD_POOL_SIZE updated", new Integer(1000), reportMaxMethodPoolSize);
51+
requestDenyList = builder.get(ConfigKey.REQUEST_DENY_LIST);
4952
Assert.assertEquals("REQUEST_DENY_LIST updated", expectRequestDenyList, requestDenyList);
5053

5154
// update invalid
@@ -62,11 +65,11 @@ public void testGetConfigAndUpdate() {
6265
configJson = new JSONObject(configString);
6366
builder.update(configJson);
6467

65-
reportResponseBody = ((Config<Boolean>)builder.getConfig(ConfigKey.REPORT_RESPONSE_BODY)).get();
68+
reportResponseBody = builder.get(ConfigKey.REPORT_RESPONSE_BODY);
6669
Assert.assertFalse("REPORT_RESPONSE_BODY not updated", reportResponseBody);
67-
reportMaxMethodPoolSize = ((Config<Integer>)builder.getConfig(ConfigKey.REPORT_MAX_METHOD_POOL_SIZE)).get();
68-
Assert.assertEquals("REPORT_MAX_METHOD_POOL_SIZE not updated", 1000, reportMaxMethodPoolSize);
69-
requestDenyList = ((Config<RequestDenyList>)builder.getConfig(ConfigKey.REQUEST_DENY_LIST)).get();
70+
reportMaxMethodPoolSize = builder.get(ConfigKey.REPORT_MAX_METHOD_POOL_SIZE);
71+
Assert.assertEquals("REPORT_MAX_METHOD_POOL_SIZE not updated", new Integer(1000), reportMaxMethodPoolSize);
72+
requestDenyList = builder.get(ConfigKey.REQUEST_DENY_LIST);
7073
Assert.assertEquals("REQUEST_DENY_LIST not updated", expectRequestDenyList, requestDenyList);
7174

7275
ConfigBuilder.clear();

dongtai-core/src/main/java/io/dongtai/iast/core/bytecode/IastClassFileTransformer.java

Lines changed: 46 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import io.dongtai.iast.core.bytecode.sca.ScaScanner;
1010
import io.dongtai.iast.core.handler.hookpoint.SpyDispatcherImpl;
1111
import io.dongtai.iast.core.handler.hookpoint.models.policy.PolicyManager;
12+
import io.dongtai.iast.core.handler.hookpoint.vulscan.dynamic.FastjsonCheck;
1213
import io.dongtai.iast.core.utils.AsmUtils;
1314
import io.dongtai.iast.core.utils.PropertyUtils;
1415
import io.dongtai.iast.core.utils.matcher.ConfigMatcher;
@@ -122,6 +123,12 @@ public byte[] transform(final ClassLoader loader,
122123
return null;
123124
}
124125

126+
if (" com/alibaba/fastjson/JSON".substring(1).equals(internalClassName)) {
127+
FastjsonCheck.setJsonClassLoader(loader);
128+
} else if (" com/alibaba/fastjson/parser/ParserConfig".substring(1).equals(internalClassName)) {
129+
FastjsonCheck.setParseConfigClassLoader(loader);
130+
}
131+
125132
if (null != loader && loader.toString().toLowerCase().contains("rasp")) {
126133
return null;
127134
}
@@ -137,45 +144,47 @@ public byte[] transform(final ClassLoader loader,
137144
}
138145
}
139146

140-
if (null != classBeingRedefined || configMatcher.canHook(internalClassName)) {
141-
byte[] sourceCodeBak = new byte[srcByteCodeArray.length];
142-
System.arraycopy(srcByteCodeArray, 0, sourceCodeBak, 0, srcByteCodeArray.length);
143-
final ClassReader cr = new ClassReader(sourceCodeBak);
147+
if (null == classBeingRedefined && !configMatcher.canHook(internalClassName, this.policyManager)) {
148+
return null;
149+
}
144150

145-
ClassContext classContext = new ClassContext(cr, loader);
146-
if (Modifier.isInterface(classContext.getModifier())) {
147-
sourceCodeBak = null;
148-
return null;
149-
}
150-
final String className = classContext.getClassName();
151-
152-
Set<String> ancestors = classDiagram.getDiagram(className);
153-
if (ancestors == null) {
154-
classDiagram.setLoader(loader);
155-
classDiagram.saveAncestors(className, classContext.getSuperClassName(), classContext.getInterfaces());
156-
ancestors = classDiagram.getAncestors(className, classContext.getSuperClassName(),
157-
classContext.getInterfaces());
158-
}
159-
classContext.setAncestors(ancestors);
160-
161-
final ClassWriter cw = createClassWriter(loader, cr);
162-
ClassVisitor cv = plugins.initial(cw, classContext, policyManager);
163-
164-
if (cv instanceof AbstractClassVisitor) {
165-
cr.accept(cv, ClassReader.EXPAND_FRAMES);
166-
AbstractClassVisitor dumpClassVisitor = (AbstractClassVisitor) cv;
167-
if (dumpClassVisitor.hasTransformed()) {
168-
if (null == classBeingRedefined) {
169-
transformMap.put(className, srcByteCodeArray);
170-
} else {
171-
transformMap.put(classBeingRedefined, srcByteCodeArray);
172-
}
173-
transformCount++;
174-
return dumpClassIfNecessary(cr.getClassName(), cw.toByteArray(), srcByteCodeArray);
151+
byte[] sourceCodeBak = new byte[srcByteCodeArray.length];
152+
System.arraycopy(srcByteCodeArray, 0, sourceCodeBak, 0, srcByteCodeArray.length);
153+
final ClassReader cr = new ClassReader(sourceCodeBak);
154+
155+
ClassContext classContext = new ClassContext(cr, loader);
156+
if (Modifier.isInterface(classContext.getModifier())) {
157+
sourceCodeBak = null;
158+
return null;
159+
}
160+
final String className = classContext.getClassName();
161+
162+
Set<String> ancestors = classDiagram.getDiagram(className);
163+
if (ancestors == null) {
164+
classDiagram.setLoader(loader);
165+
classDiagram.saveAncestors(className, classContext.getSuperClassName(), classContext.getInterfaces());
166+
ancestors = classDiagram.getAncestors(className, classContext.getSuperClassName(),
167+
classContext.getInterfaces());
168+
}
169+
classContext.setAncestors(ancestors);
170+
171+
final ClassWriter cw = createClassWriter(loader, cr);
172+
ClassVisitor cv = plugins.initial(cw, classContext, policyManager);
173+
174+
if (cv instanceof AbstractClassVisitor) {
175+
cr.accept(cv, ClassReader.EXPAND_FRAMES);
176+
AbstractClassVisitor dumpClassVisitor = (AbstractClassVisitor) cv;
177+
if (dumpClassVisitor.hasTransformed()) {
178+
if (null == classBeingRedefined) {
179+
transformMap.put(className, srcByteCodeArray);
180+
} else {
181+
transformMap.put(classBeingRedefined, srcByteCodeArray);
175182
}
183+
transformCount++;
184+
return dumpClassIfNecessary(cr.getClassName(), cw.toByteArray(), srcByteCodeArray);
176185
}
177-
sourceCodeBak = null;
178186
}
187+
sourceCodeBak = null;
179188
} catch (Throwable throwable) {
180189
DongTaiLog.warn(ErrorCode.TRANSFORM_CLASS_FAILED, internalClassName, throwable);
181190
} finally {
@@ -264,7 +273,7 @@ public Class<?>[] findForRetransform() {
264273
continue;
265274
}
266275
try {
267-
if (!configMatcher.canHook(clazz)) {
276+
if (!configMatcher.canHook(clazz, this.policyManager)) {
268277
continue;
269278
}
270279
String className = clazz.getName();
@@ -288,7 +297,7 @@ public Class<?>[] findForRetransform() {
288297
classDiagram.setDiagram(className, diagram);
289298
}
290299
for (String clazzName : diagram) {
291-
if (PolicyManager.isHookClass(clazzName) ||
300+
if (this.policyManager.isHookClass(clazzName) ||
292301
(this.policyManager.getPolicy() != null && this.policyManager.getPolicy().isMatchClass(clazzName))) {
293302
enhanceClasses[enhanceClassSize++] = clazz;
294303
break;

dongtai-core/src/main/java/io/dongtai/iast/core/bytecode/enhance/asm/AsmMethods.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,14 @@ static Method getAsmMethod(final Class<?> clazz,
218218
SpyDispatcher.class,
219219
"isFirstLevelSink"
220220
);
221+
Method SPY$enterIgnoreInternal = InnerHelper.getAsmMethod(
222+
SpyDispatcher.class,
223+
"enterIgnoreInternal"
224+
);
225+
Method SPY$leaveIgnoreInternal = InnerHelper.getAsmMethod(
226+
SpyDispatcher.class,
227+
"leaveIgnoreInternal"
228+
);
221229
Method SPY$collectMethodPool = InnerHelper.getAsmMethod(
222230
SpyDispatcher.class,
223231
"collectMethodPool",

0 commit comments

Comments
 (0)