#4728·jedis

Percent-encoded colon in URI username shifts the user/password split

Author: insaf021Created Sep 8, 2026Updated Sep 17, 2026

Problem

JedisURIHelper.getUser and getPassword read uri.getUserInfo() and then split(":", 2). URI.getUserInfo() returns the decoded form, so a percent-encoded colon (%3A) in the username has already become a literal : by the time the split runs, and the split lands on it instead of on the real separator.

For redis://us%3Aer:pw@host:6379/0 the result is user us with password er:pw, where the URI means user us:er with password pw. The client then sends AUTH us er:pw, so the wrong ACL identity is presented and the connection is refused with an error that points at the wrong user.

ACL usernames aren't restricted to URI-safe characters, and namespaced names such as svc:billing are a natural fit for them. The only way to put one in a URI is to percent-encode the colon, which is exactly the input that breaks. The same happens for any URI assembled with URLEncoder or a URI builder, since those encode : in the username as a matter of course.

One constraint on any fix: userinfo is not form data, so a literal + in a password must stay a +. Decoding the split halves has to guard against URLDecoder's plus-to-space rule.

Minimal reproducible example

No server needed:

java
URI uri = new URI("redis://us%3Aer:pw@host:9000/0");
JedisURIHelper.getUser(uri);      // "us"     (expected "us:er")
JedisURIHelper.getPassword(uri);  // "er:pw"  (expected "pw")

As a unit test in JedisURIHelperTest:

java
@Test
public void shouldKeepEncodedColonInsideUsername() throws URISyntaxException {
  URI uri = new URI("redis://us%3Aer:pw@host:9000/0");
  assertEquals("us:er", JedisURIHelper.getUser(uri));
  assertEquals("pw", JedisURIHelper.getPassword(uri));
}

On master this fails with expected: <us:er> but was: <us>.

Fix

Split uri.getRawUserInfo() instead, where an encoded colon is still %3A and only the real separator is a literal :, then percent-decode each half. Encoded @ or : in the password and a literal + behave as before. #4617 does this.