Skip to content

Commit 0007a1e

Browse files
Fix judbc detector detecting incomplete conn string and fixed invalid parsing of sql server string
1 parent a633174 commit 0007a1e

File tree

5 files changed

+58
-4
lines changed

5 files changed

+58
-4
lines changed

pkg/detectors/jdbc/jdbc.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ var _ detectors.Detector = (*Scanner)(nil)
5050
var _ detectors.CustomFalsePositiveChecker = (*Scanner)(nil)
5151

5252
var (
53-
keyPat = regexp.MustCompile(`(?i)jdbc:[\w]{3,10}:[^\s"'<>,(){}[\]&]{10,512}`)
53+
// Matches typical JDBC connection strings amd ingores any special character at the end
54+
keyPat = regexp.MustCompile(`(?i)jdbc:[\w]{3,10}:[^\s"'<>,{}[\]]{10,511}[A-Za-z0-9]`)
5455
)
5556

5657
// Keywords are used for efficiently pre-filtering chunks.

pkg/detectors/jdbc/jdbc_test.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ func TestJdbc_Pattern(t *testing.T) {
3737
<jdbc-url>jdbc:mysql:localhost:3306/mydatabase</jdbc-url>
3838
<jdbc-url>jdbc:sqlserver://x.x.x.x:1433;databaseName=MY-DB;user=MY-USER;password=MY-PASSWORD;encrypt=false</jdbc-url>
3939
<jdbc-url>jdbc:sqlserver://localhost:1433;databaseName=AdventureWorks</jdbc-url>
40+
<jdbc-url>(jdbc:mysql://testuser:testpassword@tcp(localhost:1521)/testdb)</jdbc-url>
41+
<jdbc-url>jdbc:postgresql://localhost:1521/testdb?sslmode=disable&password=testpassword&user=testuser&</jdbc-url>
4042
<working-dir>$ProjectFileDir$</working-dir>
4143
</data-source>
4244
</component>
@@ -47,6 +49,8 @@ func TestJdbc_Pattern(t *testing.T) {
4749
"jdbc:mysql:localhost:3306/mydatabase",
4850
"jdbc:sqlserver://x.x.x.x:1433;databaseName=MY-DB;user=MY-USER;password=MY-PASSWORD;encrypt=false",
4951
"jdbc:sqlserver://localhost:1433;databaseName=AdventureWorks",
52+
"jdbc:mysql://testuser:testpassword@tcp(localhost:1521)/testdb",
53+
"jdbc:postgresql://localhost:1521/testdb?sslmode=disable&password=testpassword&user=testuser",
5054
},
5155
},
5256
{
@@ -61,15 +65,19 @@ func TestJdbc_Pattern(t *testing.T) {
6165
"jdbc:oracle:thin:@host:1521:db",
6266
"jdbc:mysql://host:3306/db,other_param",
6367
"jdbc:db2://host:50000/db?param=1"
64-
]
65-
}`,
68+
"jdbc:postgresql://localhost:1521/testdb?sslmode=disable&password=testpassword&user=testuser"
69+
"jdbc:mysql://testuser:testpassword@tcp(localhost:1521)/testdb"
70+
]
71+
}`,
6672
want: []string{
6773
"jdbc:postgresql://localhost:5432/mydb",
6874
"jdbc:mysql://user:pass@host:3306/db?param=1",
6975
"jdbc:sqlite:/data/test.db",
7076
"jdbc:oracle:thin:@host:1521:db",
7177
"jdbc:mysql://host:3306/db",
7278
"jdbc:db2://host:50000/db?param=1",
79+
"jdbc:postgresql://localhost:1521/testdb?sslmode=disable&password=testpassword&user=testuser",
80+
"jdbc:mysql://testuser:testpassword@tcp(localhost:1521)/testdb",
7381
},
7482
},
7583
{

pkg/detectors/jdbc/sqlserver.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ func ParseSqlServer(ctx logContext.Context, subname string) (jdbc, error) {
5959
continue
6060
}
6161

62+
// incase there is a bridge between jdbc and odbc, and conn string looks like this odbc:server
63+
if split := strings.Split(key, ":"); len(split) > 1 {
64+
key = split[1]
65+
}
66+
6267
switch strings.ToLower(key) {
6368
case "password", "spring.datasource.password", "pwd":
6469
password = value

pkg/detectors/jdbc/sqlserver_integration_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/stretchr/testify/assert"
1313
"github.com/testcontainers/testcontainers-go"
1414
"github.com/testcontainers/testcontainers-go/modules/mssql"
15+
logContext "github.com/trufflesecurity/trufflehog/v3/pkg/context"
1516
)
1617

1718
func TestSqlServer(t *testing.T) {
@@ -81,7 +82,8 @@ func TestSqlServer(t *testing.T) {
8182
}
8283
for _, tt := range tests {
8384
t.Run(tt.input, func(t *testing.T) {
84-
j, err := parseSqlServer(tt.input)
85+
ctx := logContext.AddLogger(context.Background())
86+
j, err := ParseSqlServer(ctx, tt.input)
8587

8688
if err != nil {
8789
got := result{parseErr: true}

pkg/detectors/jdbc/sqlserver_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,3 +115,41 @@ func TestParseSqlServerUserIgnoredBug2(t *testing.T) {
115115
})
116116
}
117117
}
118+
119+
func TestParseSqlServerWithJdbcAndOdbcBridgeString(t *testing.T) {
120+
subname := "//odbc:server=localhost;port=1433;database=testdb;password=testpassword"
121+
122+
wantHost := "localhost"
123+
wantPort := "1433"
124+
wantPassword := "testpassword"
125+
wantDatabase := "testdb"
126+
127+
ctx := logContext.AddLogger(context.Background())
128+
129+
j, err := ParseSqlServer(ctx, subname)
130+
if err != nil {
131+
t.Fatalf("parseSqlServer() error = %v", err)
132+
}
133+
134+
if j == nil {
135+
t.Fatalf("parseSqlServer() returned nil, expected valid connection.")
136+
}
137+
138+
sqlServerConn, ok := j.(*SqlServerJDBC)
139+
if !ok {
140+
t.Fatalf("parseSqlServer() returned unexpected type %T, expected *SqlServerJDBC", j)
141+
}
142+
143+
if sqlServerConn.Host != wantHost+":"+wantPort {
144+
t.Errorf("Host mismatch. Got: %s, Want: %s", sqlServerConn.Host, wantHost+":"+wantPort)
145+
}
146+
147+
if sqlServerConn.Password != wantPassword {
148+
t.Errorf("Password mismatch. Got: %s, Want: %s", sqlServerConn.Password, wantPassword)
149+
}
150+
151+
if sqlServerConn.Database != wantDatabase {
152+
t.Errorf("Database mismatch. Got: %s, Want: %s", sqlServerConn.Database, wantDatabase)
153+
}
154+
155+
}

0 commit comments

Comments
 (0)