Skip to content

Commit 1eae344

Browse files
committed
Connection String
Don't output the host and port information if the port is invalid. Reduces risk of leaking password information if the password has not been correctly urlencoded. JAVA-5560
1 parent 4df1108 commit 1eae344

File tree

2 files changed

+23
-10
lines changed

2 files changed

+23
-10
lines changed

driver-core/src/main/com/mongodb/ConnectionString.java

+8-10
Original file line numberDiff line numberDiff line change
@@ -1209,7 +1209,7 @@ private List<String> parseHosts(final List<String> rawHosts) {
12091209
}
12101210
int idx = host.indexOf("]:");
12111211
if (idx != -1) {
1212-
validatePort(host, host.substring(idx + 2));
1212+
validatePort(host.substring(idx + 2));
12131213
}
12141214
} else {
12151215
int colonCount = countOccurrences(host, ":");
@@ -1218,7 +1218,7 @@ private List<String> parseHosts(final List<String> rawHosts) {
12181218
+ "Reserved characters such as ':' must be escaped according RFC 2396. "
12191219
+ "Any IPv6 address literal must be enclosed in '[' and ']' according to RFC 2732.", host));
12201220
} else if (colonCount == 1) {
1221-
validatePort(host, host.substring(host.indexOf(":") + 1));
1221+
validatePort(host.substring(host.indexOf(":") + 1));
12221222
}
12231223
}
12241224
hosts.add(host);
@@ -1227,19 +1227,17 @@ private List<String> parseHosts(final List<String> rawHosts) {
12271227
return hosts;
12281228
}
12291229

1230-
private void validatePort(final String host, final String port) {
1231-
boolean invalidPort = false;
1230+
private void validatePort(final String port) {
12321231
try {
12331232
int portInt = Integer.parseInt(port);
12341233
if (portInt <= 0 || portInt > 65535) {
1235-
invalidPort = true;
1234+
throw new IllegalArgumentException("The connection string contains an invalid host and port. "
1235+
+ "The port must be an integer between 0 and 65535.");
12361236
}
12371237
} catch (NumberFormatException e) {
1238-
invalidPort = true;
1239-
}
1240-
if (invalidPort) {
1241-
throw new IllegalArgumentException(format("The connection string contains an invalid host '%s'. "
1242-
+ "The port '%s' is not a valid, it must be an integer between 0 and 65535", host, port));
1238+
throw new IllegalArgumentException("The connection string contains an invalid host and port. "
1239+
+ "The port contains non-digit characters, it must be an integer between 0 and 65535. "
1240+
+ "Hint: username and password must be escaped according to RFC 3986.");
12431241
}
12441242
}
12451243

driver-core/src/test/unit/com/mongodb/ConnectionStringUnitTest.java

+15
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.mongodb.connection.ServerMonitoringMode;
2020
import org.junit.jupiter.api.Test;
2121
import org.junit.jupiter.params.ParameterizedTest;
22+
import org.junit.jupiter.params.provider.MethodSource;
2223
import org.junit.jupiter.params.provider.ValueSource;
2324

2425
import java.io.UnsupportedEncodingException;
@@ -27,6 +28,7 @@
2728

2829
import static org.junit.jupiter.api.Assertions.assertAll;
2930
import static org.junit.jupiter.api.Assertions.assertEquals;
31+
import static org.junit.jupiter.api.Assertions.assertFalse;
3032
import static org.junit.jupiter.api.Assertions.assertNotEquals;
3133
import static org.junit.jupiter.api.Assertions.assertNull;
3234
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -92,4 +94,17 @@ void serverMonitoringMode() {
9294
() -> new ConnectionString(DEFAULT_OPTIONS + "serverMonitoringMode=invalid"))
9395
);
9496
}
97+
98+
99+
@ParameterizedTest
100+
@ValueSource(strings = {"mongodb://foo:bar/@hostname/java?", "mongodb://foo:bar?@hostname/java/",
101+
"mongodb+srv://foo:bar/@hostname/java?", "mongodb+srv://foo:bar?@hostname/java/",
102+
"mongodb://foo:bar/@[::1]:27018", "mongodb://foo:bar?@[::1]:27018",
103+
"mongodb://foo:12345678/@hostname", "mongodb+srv://foo:12345678/@hostname"
104+
})
105+
void unescapedPasswordsShouldNotBeLeakedInExceptionMessages(final String input) {
106+
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> new ConnectionString(input));
107+
assertFalse(exception.getMessage().contains("bar"));
108+
assertFalse(exception.getMessage().contains("12345678"));
109+
}
95110
}

0 commit comments

Comments
 (0)