MM-51768: Scrub username/password from SQL datasource (#22731)

https://mattermost.atlassian.net/browse/MM-51768
```release-note
NONE
```
Этот коммит содержится в:
Agniva De Sarker
2023-04-03 23:41:51 +05:30
коммит произвёл GitHub
родитель 1762dfce22
Коммит dacac2e3ed
7 изменённых файлов: 80 добавлений и 81 удалений

Просмотреть файл

@@ -237,7 +237,9 @@ func SetupConnection(connType string, dataSource string, settings *model.SqlSett
}
for i := 0; i < DBPingAttempts; i++ {
mlog.Info("Pinging SQL", mlog.String("database", connType), mlog.String("dataSource", dataSource))
// At this point, we have passed sql.Open, so we deliberately ignore any errors.
sanitized, _ := SanitizeDataSource(*settings.DriverName, dataSource)
mlog.Info("Pinging SQL", mlog.String("database", connType), mlog.String("dataSource", sanitized))
ctx, cancel := context.WithTimeout(context.Background(), DBPingTimeoutSecs*time.Second)
defer cancel()
err = db.PingContext(ctx)

Просмотреть файл

@@ -5,6 +5,7 @@ package sqlstore
import (
"database/sql"
"errors"
"io"
"net/url"
"strconv"
@@ -206,3 +207,29 @@ func ResetReadTimeout(dataSource string) (string, error) {
config.ReadTimeout = 0
return config.FormatDSN(), nil
}
func SanitizeDataSource(driverName, dataSource string) (string, error) {
switch driverName {
case model.DatabaseDriverPostgres:
u, err := url.Parse(dataSource)
if err != nil {
return "", err
}
u.User = url.UserPassword("****", "****")
params := u.Query()
params.Del("user")
params.Del("password")
u.RawQuery = params.Encode()
return u.String(), nil
case model.DatabaseDriverMysql:
cfg, err := mysql.ParseDSN(dataSource)
if err != nil {
return "", err
}
cfg.User = "****"
cfg.Passwd = "****"
return cfg.FormatDSN(), nil
default:
return "", errors.New("invalid drivername. Not postgres or mysql.")
}
}

Просмотреть файл

@@ -6,6 +6,7 @@ package sqlstore
import (
"testing"
"github.com/mattermost/mattermost-server/v6/model"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@@ -160,3 +161,45 @@ func TestAppendMultipleStatementsFlag(t *testing.T) {
})
}
}
func TestSanitizeDataSource(t *testing.T) {
t.Run(model.DatabaseDriverPostgres, func(t *testing.T) {
testCases := []struct {
Original string
Sanitized string
}{
{
"postgres://mmuser:mostest@localhost/dummy?sslmode=disable",
"postgres://%2A%2A%2A%2A:%2A%2A%2A%2A@localhost/dummy?sslmode=disable",
},
{
"postgres://localhost/dummy?sslmode=disable&user=mmuser&password=mostest",
"postgres://%2A%2A%2A%2A:%2A%2A%2A%2A@localhost/dummy?sslmode=disable",
},
}
driver := model.DatabaseDriverPostgres
for _, tc := range testCases {
out, err := SanitizeDataSource(driver, tc.Original)
require.NoError(t, err)
assert.Equal(t, tc.Sanitized, out)
}
})
t.Run(model.DatabaseDriverMysql, func(t *testing.T) {
testCases := []struct {
Original string
Sanitized string
}{
{
"mmuser:mostest@tcp(localhost:3306)/mattermost_test?charset=utf8mb4,utf8&readTimeout=30s&writeTimeout=30s",
"****:****@tcp(localhost:3306)/mattermost_test?readTimeout=30s&writeTimeout=30s&charset=utf8mb4%2Cutf8",
},
}
driver := model.DatabaseDriverMysql
for _, tc := range testCases {
out, err := SanitizeDataSource(driver, tc.Original)
require.NoError(t, err)
assert.Equal(t, tc.Sanitized, out)
}
})
}