Skip to content

Commit da2ad60

Browse files
authored
Connection String (#1467)
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 a95b9cf commit da2ad60

File tree

2 files changed

+26
-10
lines changed

2 files changed

+26
-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

+18
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,20 @@ 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+
"mongodb://foo:12345678/@hostname", "mongodb+srv://foo:12345678/@hostname",
105+
"mongodb://foo:12345678%40hostname", "mongodb+srv://foo:12345678%40hostname",
106+
"mongodb://foo:12345678@bar@hostname", "mongodb+srv://foo:12345678@bar@hostname"
107+
})
108+
void unescapedPasswordsShouldNotBeLeakedInExceptionMessages(final String input) {
109+
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> new ConnectionString(input));
110+
assertFalse(exception.getMessage().contains("bar"));
111+
assertFalse(exception.getMessage().contains("12345678"));
112+
}
95113
}

0 commit comments

Comments
 (0)