ReviewOS

stacks/ts-cache

RedisDriver ignores host, port, password, database and tls unless url is given, and has no username

#3093
Closed glennmichael123 opened this 3 days ago ·
3 days ago

RedisDriver connects to REDIS_URL, or else redis://localhost:6379, whatever host, port, password, database and tls say. Only an explicit url is honoured. username is not supported at all.

Cause (src/drivers/redis.ts, v0.1.7; main has no changes to this file)

url: options.url ?? process.env.REDIS_URL ?? 'redis://localhost:6379',

url always ends up set, and buildConnectionUrl() returns it before reaching the branch that builds a URL from the other options:

if (this.options.url) {
  return this.options.url
}

So that branch is dead code. It also has no place for a username: const auth = this.options.password ? :${this.options.password}@ : '', with the password not URL-encoded.

Reproduction (Redis 8.8.0 on 127.0.0.1:56379; another Redis already on 6379)

Through @stacksjs/cache's createRedisCache, which passes these options straight to createCache({ driver: 'redis', ... }). The number of connections the client made to 56379 is total_connections_received before and after, minus the measuring call:

OptionsConnections to 56379Result
{ host: '127.0.0.1', port: 56379 }0MISCONF from the server on 6379
+ password0same
+ username (an ACL user)0same
{ url: 'redis://probe:probe-pass@127.0.0.1:56379/0' } (control)1stored and read back

An app whose Redis is on another host, port or database, or behind an ACL user, writes its cache to whatever answers on localhost:6379, or fails.

Expected

  • An explicit url wins.
  • Otherwise, if any of host, port, username, password, database or tls is given, the URL is built from them.
  • Only when none of them is given does the driver fall back to REDIS_URL, then redis://localhost:6379.
  • username is supported, and both credentials are URL-encoded.

Found while auditing @stacksjs/cache for 1.0 (stacksjs/stacks#1169).

Sign in to comment on this issue.