aws / aws/aws-advanced-go-wrapper

MySQL DSN containing a space in the user or password is detected as a Postgres key/value DSN

Open
#587 1 comment 0 reactions 0 assignees View on GitHub
bug pending release
Dominant language
Go
Stars
78
Forks
12
Avg merge
3d 20h
Merged PRs (30d)
13

Description

### Describe the bug

A MySQL DSN whose user name or password contains a space is parsed as a Postgres key/value DSN.

[`isDsnMySql`](https://github.com/aws/aws-advanced-go-wrapper/blob/877b430/awssql/property_util/dsn_parser.go#L209-L211) rejects any DSN with whitespace between tokens, so MySQL is ruled out before `mySqlDsnPattern` is even evaluated. Detection then falls through to `isDsnPgxKeyValueString`, and that pattern is unanchored, so a trailing `?parseTime=true` is enough to match.

`go-sql-driver/mysql` does not unescape the user or password, so `%20` stays literal. The space has to be a real space, which leaves no way to connect with those credentials through the wrapper.

### Expected Behavior

The same result as the DSN without the space. Protocol `mysql`, with user, password, host, port and database parsed out. `go-sql-driver/mysql` accepts these DSNs, and `Config.FormatDSN()` emits the space unescaped.

### What plugins are used? What other connection properties were set?

No plugins. No extra connection properties.

### Current Behavior

`ParseDsn` returns no error and two properties, with the front of the DSN swallowed into a single key:

| DSN | protocol | properties |
|---|---|---|
| `user:pass@tcp(myhost:3306)/db?parseTime=true` | `mysql` | 8, correct |
| `user:pa ss@tcp(myhost:3306)/db?parseTime=true` | `postgresql` | `{protocol: "postgresql", "user:pa ss@tcp(myhost:3306)/db?parseTime": "true"}` |

Host, port and credentials are gone and nothing reports a failure, so `GetHostsFromDsn` and `ParseUserFromDsn` just return empty values. `MaskSensitiveInfoFromDsn` branches on the same predicates in the same order, so credentials in an affected DSN also end up unmasked.

### Reproduction Steps

No database needed.

```go
package main

import (
"fmt"

"github.com/aws/aws-advanced-go-wrapper/awssql/v2/property_util"
)

func main() {
dsn := "user:pa ss@tcp(myhost:3306)/db?parseTime=true"

proto, _ := property_util.GetProtocol(dsn)
props, err := property_util.ParseDsn(dsn)
fmt.Println(proto, err, props.GetAllEntries())
}
```

On awssql/v2 v2.0.3:

```
postgresql map[protocol:postgresql user:pa ss@tcp(myhost:3306)/db?parseTime:true]
```

Removing the space from the password gives `mysql` and the eight expected properties.

### Possible Solution

Detect pgx key/value DSNs with an anchored match rather than ruling MySQL out by whitespace, and check pgx key/value before MySQL, since `mySqlDsnPattern`'s groups are all optional and it matches almost anything.

One catch: simply wrapping the current pattern in `^(...)+$` is not enough. Its value class has no space or backslash, so it would then reject pgx DSNs that quote a value because it contains a space, like `host=localhost password='my pass' dbname=x`. Those would fall through to `mySqlDsnPattern` and get misdetected as MySQL instead. The value grammar needs to accept what `parsePgxKeywordValueSettings` already accepts.

I have this working locally with the existing unit tests passing, and can send a PR if the approach looks right.

### Additional Information/Context

The whitespace check was added in #130 to stop pgx key/value DSNs from matching `mySqlDsnPattern`. Anchoring handles that case without the side effect.

`.test/test/dsn_parser_test.go` covers trailing spaces but not a space inside the credentials.

### The AWS Advanced Go Wrapper version used

`awssql/v2` v2.0.3, `mysql-driver` v1.1.3

### Go version used

go1.26.4 darwin/arm64

### Operating System and version

macOS 26.5 (arm64)

Contributor guide

Open the contributing guide

Research direction

Start in awssql/property_util/dsn_parser.go by reading the DSN detection predicates, ParseDsn, MaskSensitiveInfoFromDsn, and parsePgxKeywordValueSettings. Run .test/test/dsn_parser_test.go and add coverage for spaces in MySQL credentials and quoted pgx values. Done means both DSN forms are detected correctly, parsed properties and protocol are preserved, and affected credentials remain masked.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, mysql, postgresql
Domain
databases
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.