Skip to content

Commit

Permalink
Security/128 fix security issues (#129)
Browse files Browse the repository at this point in the history
* prepare new release

* update driver version

* update go version and exasol in CI

* update changelog

* update golangci-lint

* add error checks

* restore

* rewrite checks. and test cases

* improve changelog

* avoid defer in loop. reuse connections in test cases where is possible
  • Loading branch information
YotillaAntoni authored Feb 10, 2025
1 parent f9283be commit 1ccbc5f
Show file tree
Hide file tree
Showing 13 changed files with 105 additions and 34 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/ci-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ jobs:
matrix-build:
strategy:
matrix:
go: ["1.21.12", "1.22.5"]
db: ["7.1.26", "8.27.0"]
go: ["1.22.12", "1.23.6"]
db: ["7.1.30", "8.32.0"]
env:
DEFAULT_GO: "1.21.12"
DEFAULT_DB: "8.27.0"
DEFAULT_GO: "1.22.12"
DEFAULT_DB: "8.32.0"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-go-${{ matrix.go }}-db-${{ matrix.db }}
cancel-in-progress: true
Expand All @@ -37,7 +37,7 @@ jobs:
- name: golangci-lint
uses: golangci/golangci-lint-action@v6
with:
version: v1.59.1
version: v1.63.4
skip-cache: true # Caching already done by actions/cache

- name: Enable testcontainer reuse
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/dependencies_check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
id: go
uses: actions/setup-go@v5
with:
go-version: "1.22.5"
go-version: "1.22.12"
cache: true

- name: Install vulncheck
Expand Down
2 changes: 1 addition & 1 deletion .project-keeper.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
sources:
- type: golang
path: go.mod
version: 1.0.11
version: 1.0.12
excludes:
# Releases are done with Release Droid because PK does not yet support release process for Go projects.
- "E-PK-CORE-26: 'release_config.yml' exists but must not exist. Reason: Release-droid configuration is replaced by release.yml"
6 changes: 3 additions & 3 deletions dependencies.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions doc/changes/changelog.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 28 additions & 0 deletions doc/changes/changes_1.0.12.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Exasol Driver go 1.0.12, released 2025-02-10

Code name: Update to go 1.22 and improved error handling

## Summary

This release updates to go 1.22 and updates version used in CI pipeline to fix vulnerabilities in the go standard library:
- GO-2024-3107
- GO-2024-3105
- GO-2024-3106

It also improves the detection of errors during login.

## Security

* #128: Fix security issues in dependencies / standard library

## Dependency Updates

### Compile Dependency Updates

* Updated `golang:1.21` to `1.22`
* Updated `github.com/stretchr/testify:v1.9.0` to `v1.10.0`
* Updated `github.com/exasol/exasol-test-setup-abstraction-server/go-client:v0.3.9` to `v0.3.10`

### Test Dependency Updates

* Updated `golang.org/x/sync:v0.7.0` to `v0.11.0`
10 changes: 5 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
module github.com/exasol/exasol-driver-go

go 1.21
go 1.22

require (
github.com/exasol/error-reporting-go v0.2.0
github.com/exasol/exasol-test-setup-abstraction-server/go-client v0.3.9
github.com/exasol/exasol-test-setup-abstraction-server/go-client v0.3.10
github.com/gorilla/websocket v1.5.3
github.com/stretchr/testify v1.9.0
github.com/stretchr/testify v1.10.0
go.uber.org/goleak v1.3.0
golang.org/x/sync v0.7.0
golang.org/x/sync v0.11.0
gopkg.in/yaml.v3 v3.0.1
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/rogpeppe/go-internal v1.13.1 // indirect
github.com/stretchr/objx v0.5.2 // indirect
golang.org/x/net v0.34.0 // indirect
)
9 changes: 9 additions & 0 deletions go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion internal/version/version.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package version

const DriverVersion = "v1.0.11"
const DriverVersion = "v1.0.12"
29 changes: 15 additions & 14 deletions itest/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,9 @@ var dereferenceInt = func(v any) any { return *(v.(*int)) }
var dereferenceBool = func(v any) any { return *(v.(*bool)) }

func (suite *IntegrationTestSuite) TestQueryDataTypesCast() {
database := suite.openConnection(suite.createDefaultConfig())
defer database.Close()

for i, testCase := range []struct {
testDescription string
sqlValue string
Expand Down Expand Up @@ -290,8 +293,6 @@ func (suite *IntegrationTestSuite) TestQueryDataTypesCast() {
{"bool to bool", "true", "BOOLEAN", new(bool), true, dereferenceBool},
{"bool to string", "false", "BOOLEAN", new(string), "false", dereferenceString},
} {
database := suite.openConnection(suite.createDefaultConfig())
defer database.Close()
suite.Run(fmt.Sprintf("Cast Test %02d %s: %s", i, testCase.testDescription, testCase.sqlType), func() {
rows, err := database.Query(fmt.Sprintf("SELECT CAST(%s AS %s)", testCase.sqlValue, testCase.sqlType))
onError(err)
Expand All @@ -305,6 +306,12 @@ func (suite *IntegrationTestSuite) TestQueryDataTypesCast() {
}

func (suite *IntegrationTestSuite) TestPreparedStatementArgsConverted() {
database := suite.openConnection(suite.createDefaultConfig().Autocommit(false))
schemaName := "DATATYPE_TEST"
_, err := database.Exec("CREATE SCHEMA " + schemaName)
onError(err)
defer suite.cleanup(database, schemaName)

type TestCase struct {
sqlValue any
sqlType string
Expand Down Expand Up @@ -390,12 +397,6 @@ func (suite *IntegrationTestSuite) TestPreparedStatementArgsConverted() {
boolTestCase(true, "BOOLEAN", true),
boolTestCase(false, "BOOLEAN", false),
} {
database := suite.openConnection(suite.createDefaultConfig().Autocommit(false))
schemaName := "DATATYPE_TEST"
_, err := database.Exec("CREATE SCHEMA " + schemaName)
onError(err)
defer suite.cleanup(database, schemaName)

suite.Run(fmt.Sprintf("%02d Column type %s accepts values of type %T", i, testCase.sqlType, testCase.sqlValue), func() {
tableName := fmt.Sprintf("%s.TAB_%d", schemaName, i)
_, err = database.Exec(fmt.Sprintf("CREATE TABLE %s (col %s)", tableName, testCase.sqlType))
Expand Down Expand Up @@ -433,6 +434,12 @@ func (suite *IntegrationTestSuite) TestPreparedStatementArgsConversionFails() {
}

func (suite *IntegrationTestSuite) TestScanTypeUnsupported() {
database := suite.openConnection(suite.createDefaultConfig().Autocommit(false))
schemaName := "DATATYPE_TEST"
_, err := database.Exec("CREATE SCHEMA " + schemaName)
onError(err)
defer suite.cleanup(database, schemaName)

for i, testCase := range []struct {
sqlValue any
sqlType string
Expand All @@ -443,12 +450,6 @@ func (suite *IntegrationTestSuite) TestScanTypeUnsupported() {
{time.Date(2024, time.June, 18, 17, 22, 13, 123456789, time.UTC), "TIMESTAMP", new(time.Time), `unsupported Scan, storing driver.Value type string into type *time.Time`},
{time.Date(2024, time.June, 18, 17, 22, 13, 123456789, time.UTC), "TIMESTAMP WITH LOCAL TIME ZONE", new(time.Time), `unsupported Scan, storing driver.Value type string into type *time.Time`},
} {
database := suite.openConnection(suite.createDefaultConfig().Autocommit(false))
schemaName := "DATATYPE_TEST"
_, err := database.Exec("CREATE SCHEMA " + schemaName)
onError(err)
defer suite.cleanup(database, schemaName)

suite.Run(fmt.Sprintf("Scan fails %02d %s", i, testCase.sqlType), func() {
tableName := fmt.Sprintf("%s.TAB_%d", schemaName, i)
_, err = database.Exec(fmt.Sprintf("CREATE TABLE %s (col %s)", tableName, testCase.sqlType))
Expand Down
12 changes: 10 additions & 2 deletions pkg/connection/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"encoding/base64"
"encoding/hex"
"fmt"
"math"
"math/big"
"os/user"
"runtime"
Expand Down Expand Up @@ -366,11 +367,18 @@ func (c *Connection) prepareLoginViaPassword(ctx context.Context) (string, error
return "", err
}

pubKeyMod, _ := hex.DecodeString(loginResponse.PublicKeyModulus)
pubKeyMod, err := hex.DecodeString(loginResponse.PublicKeyModulus)
if err != nil {
return "", fmt.Errorf("invalid publicKeyModulus in login response: %w", err)
}

var modulus big.Int
modulus.SetBytes(pubKeyMod)

pubKeyExp, _ := strconv.ParseUint(loginResponse.PublicKeyExponent, 16, 32)
pubKeyExp, err := strconv.ParseUint(loginResponse.PublicKeyExponent, 16, 32)
if err != nil || pubKeyExp > math.MaxInt32 {
return "", fmt.Errorf("invalid publicKeyExponent in login response: %q", loginResponse.PublicKeyExponent)
}

pubKey := rsa.PublicKey{
N: &modulus,
Expand Down
26 changes: 25 additions & 1 deletion pkg/connection/connection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -340,12 +340,36 @@ func (suite *ConnectionTestSuite) TestPasswordLoginFailsInitialRequest() {

func (suite *ConnectionTestSuite) TestPasswordLoginFailsEncryptingPasswordRequest() {
suite.websocketMock.SimulateOKResponse(types.LoginCommand{Command: types.Command{Command: "login"}, ProtocolVersion: 42},
types.PublicKeyResponse{PublicKeyPem: "", PublicKeyModulus: "", PublicKeyExponent: ""})
types.PublicKeyResponse{PublicKeyPem: "", PublicKeyModulus: "", PublicKeyExponent: "FF"})
conn := suite.createOpenConnection()
err := conn.Login(context.Background())
suite.EqualError(err, driver.ErrBadConn.Error())
}

func (suite *ConnectionTestSuite) TestPasswordLoginFailsWithInvalidModulus() {
suite.websocketMock.SimulateOKResponse(types.LoginCommand{Command: types.Command{Command: "login"}, ProtocolVersion: 42},
types.PublicKeyResponse{PublicKeyPem: "", PublicKeyModulus: "ZZZ", PublicKeyExponent: ""})
conn := suite.createOpenConnection()
err := conn.Login(context.Background())
suite.EqualError(err, "invalid publicKeyModulus in login response: encoding/hex: invalid byte: U+005A 'Z'")
}

func (suite *ConnectionTestSuite) TestPasswordLoginFailsWithInvalidExponent() {
suite.websocketMock.SimulateOKResponse(types.LoginCommand{Command: types.Command{Command: "login"}, ProtocolVersion: 42},
types.PublicKeyResponse{PublicKeyPem: "", PublicKeyModulus: "", PublicKeyExponent: "1FFFFFFFF"})
conn := suite.createOpenConnection()
err := conn.Login(context.Background())
suite.EqualError(err, `invalid publicKeyExponent in login response: "1FFFFFFFF"`)
}

func (suite *ConnectionTestSuite) TestPasswordLoginFailsWithOutOfBoundsInt() {
suite.websocketMock.SimulateOKResponse(types.LoginCommand{Command: types.Command{Command: "login"}, ProtocolVersion: 42},
types.PublicKeyResponse{PublicKeyPem: "", PublicKeyModulus: "", PublicKeyExponent: "FFFFFFFF"})
conn := suite.createOpenConnection()
err := conn.Login(context.Background())
suite.EqualError(err, `invalid publicKeyExponent in login response: "FFFFFFFF"`)
}

func (suite *ConnectionTestSuite) TestPasswordLoginSuccess() {
suite.simulatePasswordLoginSuccess()
conn := suite.createOpenConnection()
Expand Down
2 changes: 1 addition & 1 deletion pkg/integrationTesting/dbTestSetup.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"github.com/stretchr/testify/suite"
)

const defaultExasolDbVersion = "8.27.0"
const defaultExasolDbVersion = "8.32.0"

type DbTestSetup struct {
suite *suite.Suite
Expand Down

0 comments on commit 1ccbc5f

Please sign in to comment.