Skip to content

URL encoding for passwords in MongoDB connection strings #4903

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jorgerod opened this issue Feb 21, 2025 · 7 comments
Closed

URL encoding for passwords in MongoDB connection strings #4903

jorgerod opened this issue Feb 21, 2025 · 7 comments
Labels
for: stackoverflow A question that's better suited to stackoverflow.com

Comments

@jorgerod
Copy link
Contributor

Description:

Hello

I am writing to request a feature enhancement related to the handling of passwords in MongoDB connection strings. Currently, when a password contains special characters (in my case, %), it can cause issues when establishing a connection to the database. This is because these characters are not URL-encoded, leading to potential misinterpretation of the connection string.

Use Case:

For example, if a password is p%ssword, the connection string would look like this:

spring.data.mongodb.uri: mongodb+srv://myuser:myp%[email protected]

throws the following exception:

Caused by: java.lang.IllegalArgumentException: URLDecoder: Illegal hex characters in escape (%) pattern - Error at index 1 in: "as"
	at java.base/java.net.URLDecoder.decode(URLDecoder.java:237) ~[na:na]
	at java.base/java.net.URLDecoder.decode(URLDecoder.java:147) ~[na:na]
	at com.mongodb.ConnectionString.urldecode(ConnectionString.java:1289) ~[mongodb-driver-core-5.2.1.jar:na]
	at com.mongodb.ConnectionString.<init>(ConnectionString.java:411) ~[mongodb-driver-core-5.2.1.jar:na]
	at com.mongodb.ConnectionString.<init>(ConnectionString.java:343) ~[mongodb-driver-core-5.2.1.jar:na]
	at org.springframework.boot.autoconfigure.mongo.PropertiesMongoConnectionDetails.getConnectionString(PropertiesMongoConnectionDetails.java:49) ~[spring-boot-autoconfigure-3.4.3.jar:3.4.3]
	at org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration$MongoClientSettingsConfiguration.standardMongoSettingsCustomizer(MongoAutoConfiguration.java:74) ~[spring-boot-autoconfigure-3.4.3.jar:3.4.3]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:569) ~[na:na]
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.lambda$instantiate$0(SimpleInstantiationStrategy.java:171) ~[spring-beans-6.2.3.jar:6.2.3]

To make it work, we would need to manually URL-encode the password. However, our challenge is that we do not have direct access to the password, as it is injected via an environment variable and stored in a secure vault. This means we cannot pre-encode it before it is passed to the application.

Would it be possible to add automatic encoding to the spring.data.mongodb.uri property to handle this scenario more seamlessly?

Thank you very much

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Feb 21, 2025
@mp911de
Copy link
Member

mp911de commented Feb 21, 2025

Connection strings are handled fully by the MongoDB driver (see the stack trace using ConnectionString.urldecode(…)). URL encoding uses % escape syntax for escaping special characters and in consequence, you need to URLencode your passwords to ensure proper escape sequences.

@mp911de mp911de closed this as not planned Won't fix, can't repro, duplicate, stale Feb 21, 2025
@mp911de mp911de added for: stackoverflow A question that's better suited to stackoverflow.com and removed status: waiting-for-triage An issue we've not yet triaged labels Feb 21, 2025
@aaguerreberre-indtx
Copy link

Connection strings are handled fully by the MongoDB driver (see the stack trace using ConnectionString.urldecode(…)). URL encoding uses % escape syntax for escaping special characters and in consequence, you need to URLencode your passwords to ensure proper escape sequences.

If I understand your proposal, you're suggesting to take action on the password outside the application itself (be it on the file or the safe it comes from) and make it URL safe at that point?

@mp911de
Copy link
Member

mp911de commented Mar 13, 2025

It's either-or:

  1. Either make the password URL-safe and keep it as part of the URL
  2. Or provide the password as-is through spring.data.mongodb.username/spring.data.mongodb.password

FWIW, there's also another, more elaborate variant used by e.g. Spring Vault that provides a PropertySource exposing spring.data.mongodb.username/spring.data.mongodb.password properties with managed credentials.

@aaguerreberre-indtx
Copy link

@jorgerod
Copy link
Contributor Author

It's either-or:

  1. Either make the password URL-safe and keep it as part of the URL
  2. Or provide the password as-is through spring.data.mongodb.username/spring.data.mongodb.password

FWIW, there's also another, more elaborate variant used by e.g. Spring Vault that provides a PropertySource exposing spring.data.mongodb.username/spring.data.mongodb.password properties with managed credentials.

Thank you very much for your reply @mp911de

I see a bit of inconsistency between the two flavors.

  • If it's username and password (without the uri) spring-data-mongodb does the encoded
  • If it is uri, spring-data-mongodb does not do the encoding.

Wouldn't there be a way to do it with the uri?

@mp911de
Copy link
Member

mp911de commented Mar 13, 2025

Good catch, I entirely missed that Spring Boot backs off from username/password properties when using the connection URL. While that approach for sure had its place in earlier times, now that providing credentials through improved means I think we should revisit that arrangement (see spring-projects/spring-boot#17215 for an earlier discussion).

For JDBC, some URL's may contain contain authentication details, however, Boot picks up JDBC username/password properties and routes these accordingly providing much more flexibility and a proper separation between endpoint and authentication concerns.

@mp911de
Copy link
Member

mp911de commented Mar 13, 2025

I filed spring-projects/spring-boot#44712

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
for: stackoverflow A question that's better suited to stackoverflow.com
Projects
None yet
Development

No branches or pull requests

4 participants