Skip to content

Commit 72f6257

Browse files
authored
fix: escape special characters in postgres password (#16510)
Fixes: #16319 This PR modifies existing escaping logic for special characters in Postgres password, so it does fail on edge cases like `#` or `$` when parser recognizes as invalid port.
1 parent 700a453 commit 72f6257

File tree

2 files changed

+18
-2
lines changed

2 files changed

+18
-2
lines changed

cli/server.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2565,6 +2565,8 @@ func parseExternalAuthProvidersFromEnv(prefix string, environ []string) ([]coder
25652565
return providers, nil
25662566
}
25672567

2568+
var reInvalidPortAfterHost = regexp.MustCompile(`invalid port ".+" after host`)
2569+
25682570
// If the user provides a postgres URL with a password that contains special
25692571
// characters, the URL will be invalid. We need to escape the password so that
25702572
// the URL parse doesn't fail at the DB connector level.
@@ -2573,7 +2575,11 @@ func escapePostgresURLUserInfo(v string) (string, error) {
25732575
// I wish I could use errors.Is here, but this error is not declared as a
25742576
// variable in net/url. :(
25752577
if err != nil {
2576-
if strings.Contains(err.Error(), "net/url: invalid userinfo") {
2578+
// Warning: The parser may also fail with an "invalid port" error if the password contains special
2579+
// characters. It does not detect invalid user information but instead incorrectly reports an invalid port.
2580+
//
2581+
// See: https://github.com/coder/coder/issues/16319
2582+
if strings.Contains(err.Error(), "net/url: invalid userinfo") || reInvalidPortAfterHost.MatchString(err.Error()) {
25772583
// If the URL is invalid, we assume it is because the password contains
25782584
// special characters that need to be escaped.
25792585

cli/server_internal_test.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,13 +351,23 @@ func TestEscapePostgresURLUserInfo(t *testing.T) {
351351
output: "",
352352
err: xerrors.New("parse postgres url: parse \"postgres://local host:5432/coder\": invalid character \" \" in host name"),
353353
},
354+
{
355+
input: "postgres://coder:co?der@localhost:5432/coder",
356+
output: "postgres://coder:co%3Fder@localhost:5432/coder",
357+
err: nil,
358+
},
359+
{
360+
input: "postgres://coder:co#der@localhost:5432/coder",
361+
output: "postgres://coder:co%23der@localhost:5432/coder",
362+
err: nil,
363+
},
354364
}
355365
for _, tc := range testcases {
356366
tc := tc
357367
t.Run(tc.input, func(t *testing.T) {
358368
t.Parallel()
359369
o, err := escapePostgresURLUserInfo(tc.input)
360-
require.Equal(t, tc.output, o)
370+
assert.Equal(t, tc.output, o)
361371
if tc.err != nil {
362372
require.Error(t, err)
363373
require.EqualValues(t, tc.err.Error(), err.Error())

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy