Skip to content

Commit 849cd3d

Browse files
authored
[Fix] Fix vulnerabilities in the present SDK version (#383)
## What changes are proposed in this pull request? - **What** : - Update commons.io to fix the [CVE in the present version](https://mvnrepository.com/artifact/com.databricks/databricks-sdk-java/0.34.0). Looks like depandabot PRs are no longer being created/merged. [[Link](https://github.com/databricks/databricks-sdk-java/pull/261/files)] - Change ini4j configuration because of vulnerability. - **Why** - ini4j 0.5.4 version has an infinite loop situation in the following piece of code. This loop can cause excessive memory and CPU usage, potentially crashing the application. Alternate libraries like Apache Commons Configuration gracefully handle the situation (by limiting the recursions internally). I will raise a PR on SDK later today to replace the ini4j library. Moreover : the official site of ini4j [is up for sale](http://www.ini4j.org/) and the last update to this maven package was done in [2015](https://mvnrepository.com/artifact/org.ini4j/ini4j). There is no reason we should continue to use this package. ``` Ini ini = new Ini(); ini.load(new ByteArrayInputStream(""" [deploy] a = ${test/a} b = ${doc/b} [test] a = ${deploy/a} b = ${deploy/b} [doc] a = 15 b = 45 """.getBytes(StandardCharsets.UTF_8))); // Will cause stack overflow ini.get("deploy").fetch("a"); ``` ## How is this tested? - The existing unit tests run fine.
1 parent 5deef7d commit 849cd3d

File tree

2 files changed

+25
-24
lines changed

2 files changed

+25
-24
lines changed

databricks-sdk-java/pom.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@
4949
<scope>provided</scope>
5050
</dependency>
5151
<dependency>
52-
<groupId>org.ini4j</groupId>
53-
<artifactId>ini4j</artifactId>
54-
<version>0.5.4</version>
52+
<groupId>org.apache.commons</groupId>
53+
<artifactId>commons-configuration2</artifactId>
54+
<version>2.11.0</version>
5555
<scope>compile</scope>
5656
</dependency>
5757
<dependency>
@@ -67,7 +67,7 @@
6767
<dependency>
6868
<groupId>commons-io</groupId>
6969
<artifactId>commons-io</artifactId>
70-
<version>2.13.0</version>
70+
<version>2.14.0</version>
7171
</dependency>
7272
<dependency>
7373
<groupId>org.junit.jupiter</groupId>

databricks-sdk-java/src/main/java/com/databricks/sdk/core/ConfigLoader.java

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
package com.databricks.sdk.core;
22

33
import com.databricks.sdk.core.utils.Environment;
4-
import java.io.File;
54
import java.io.FileNotFoundException;
5+
import java.io.FileReader;
66
import java.io.IOException;
77
import java.lang.reflect.Field;
88
import java.net.MalformedURLException;
99
import java.net.URL;
1010
import java.nio.file.Paths;
1111
import java.util.*;
12-
import org.ini4j.Ini;
13-
import org.ini4j.Profile;
12+
import org.apache.commons.configuration2.INIConfiguration;
13+
import org.apache.commons.configuration2.SubnodeConfiguration;
14+
import org.apache.commons.configuration2.ex.ConfigurationException;
1415
import org.slf4j.Logger;
1516
import org.slf4j.LoggerFactory;
1617

@@ -40,7 +41,7 @@ public static DatabricksConfig resolve(DatabricksConfig cfg) throws DatabricksEx
4041
}
4142
}
4243

43-
static void loadFromEnvironmentVariables(DatabricksConfig cfg) throws IllegalAccessException {
44+
static void loadFromEnvironmentVariables(DatabricksConfig cfg) {
4445
if (cfg.getEnv() == null) {
4546
return;
4647
}
@@ -57,7 +58,7 @@ static void loadFromEnvironmentVariables(DatabricksConfig cfg) throws IllegalAcc
5758
}
5859
accessor.setValueOnConfig(cfg, env);
5960
}
60-
} catch (DatabricksException e) {
61+
} catch (DatabricksException | IllegalAccessException e) {
6162
String msg =
6263
String.format("%s auth: %s", cfg.getCredentialsProvider().authType(), e.getMessage());
6364
throw new DatabricksException(msg, e);
@@ -86,46 +87,46 @@ static void loadFromConfig(DatabricksConfig cfg) throws IllegalAccessException {
8687
configFile = configFile.replaceFirst("^~", userHome);
8788
}
8889

89-
Ini ini = parseDatabricksCfg(configFile, isDefaultConfig);
90+
INIConfiguration ini = parseDatabricksCfg(configFile, isDefaultConfig);
9091
if (ini == null) return;
92+
9193
String profile = cfg.getProfile();
9294
boolean hasExplicitProfile = !isNullOrEmpty(profile);
9395
if (!hasExplicitProfile) {
9496
profile = "DEFAULT";
9597
}
96-
97-
Profile.Section section = ini.get(profile);
98-
if (section == null && !hasExplicitProfile) {
98+
SubnodeConfiguration section = ini.getSection(profile);
99+
boolean sectionNotPresent = section == null || section.isEmpty();
100+
if (sectionNotPresent && !hasExplicitProfile) {
99101
LOG.info("{} has no {} profile configured", configFile, profile);
100102
return;
101103
}
102-
103-
if (section == null) {
104+
if (sectionNotPresent) {
104105
String msg = String.format("resolve: %s has no %s profile configured", configFile, profile);
105106
throw new DatabricksException(msg);
106107
}
107108

108109
for (ConfigAttributeAccessor accessor : accessors) {
109-
String value = section.get(accessor.getName());
110+
String value = section.getString(accessor.getName());
110111
if (!isNullOrEmpty(accessor.getValueFromConfig(cfg))) {
111112
continue;
112113
}
113114
accessor.setValueOnConfig(cfg, value);
114115
}
115116
}
116117

117-
private static Ini parseDatabricksCfg(String configFile, boolean isDefaultConfig) {
118-
Ini ini = new Ini();
119-
try {
120-
ini.load(new File(configFile));
118+
private static INIConfiguration parseDatabricksCfg(String configFile, boolean isDefaultConfig) {
119+
INIConfiguration iniConfig = new INIConfiguration();
120+
try (FileReader reader = new FileReader(configFile)) {
121+
iniConfig.read(reader);
121122
} catch (FileNotFoundException e) {
122123
if (isDefaultConfig) {
123124
return null;
124125
}
125-
} catch (IOException e) {
126+
} catch (IOException | ConfigurationException e) {
126127
throw new DatabricksException("Cannot load " + configFile, e);
127128
}
128-
return ini;
129+
return iniConfig;
129130
}
130131

131132
public static void fixHostIfNeeded(DatabricksConfig cfg) {
@@ -230,12 +231,12 @@ public static String debugString(DatabricksConfig cfg) {
230231
if (!attrsUsed.isEmpty()) {
231232
buf.add(String.format("Config: %s", String.join(", ", attrsUsed)));
232233
} else {
233-
buf.add(String.format("Config: <empty>"));
234+
buf.add("Config: <empty>");
234235
}
235236
if (!envsUsed.isEmpty()) {
236237
buf.add(String.format("Env: %s", String.join(", ", envsUsed)));
237238
} else {
238-
buf.add(String.format("Env: <none>"));
239+
buf.add("Env: <none>");
239240
}
240241
return String.join(". ", buf);
241242
} catch (IllegalAccessException e) {

0 commit comments

Comments
 (0)