Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release - Fix path traversal bug for sqlite, new clickhouse options, and support for OpenAI-like URLs #329

Open
wants to merge 36 commits into
base: release
Choose a base branch
from

Conversation

modelorona
Copy link
Collaborator

@modelorona modelorona commented Jan 27, 2025

✨ Improvements

Added new clickhouse options for HTTP

  • Thanks to the contribution by @Slach, we've got additional options for clickhouse support, HTTP protocol, TLS mode, readonly and debug.

Support for OpenAI-like URLs

  • Thanks to the contribution by @learningpro, we support OpenAI-like URLs now. Check the readme to see how to get started!

🐛 Bug Fixes

Path traversal issue for sqlite

  • Resolved an issue with how the database location for sqlite was being parsed resulting in the possibility of path traversal. Thanks to @nnse for catching that one!

Parameter injection issue for MySQL

  • Resolved an issue where it was possible to inject parameters using the UI. Alongside this, we took the time to go through all of the other connectors and check how we're handling input. Please let us know if you find anything out of place! Thanks to @nnse for catching that one!

Thank you to everyone who contributed to this release! 🚀
Your feedback and support are invaluable.

@@ -72,7 +72,7 @@
query += fmt.Sprintf("\nSETTINGS %s", strings.Join(settingsClauses, ", "))
}

err = conn.Exec(context.Background(), query)
_, err = conn.ExecContext(context.Background(), query)

Check failure

Code scanning / CodeQL

Database query built from user-controlled sources High

This query depends on a
user-provided value
.
This query depends on a
user-provided value
.
This query depends on a
user-provided value
.
This query depends on a
user-provided value
.

Copilot Autofix AI 7 days ago

To fix the problem, we need to ensure that user input is safely embedded into the SQL query. This can be achieved by using parameterized queries or prepared statements. In this case, we will use parameterized queries to avoid SQL injection vulnerabilities.

  1. Modify the AddStorageUnit function to use parameterized queries for the schema and storageUnit parameters.
  2. Use sql.Named to safely include the schema and storageUnit parameters in the query.
Suggested changeset 1
core/src/plugins/clickhouse/add.go

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/core/src/plugins/clickhouse/add.go b/core/src/plugins/clickhouse/add.go
--- a/core/src/plugins/clickhouse/add.go
+++ b/core/src/plugins/clickhouse/add.go
@@ -52,4 +52,4 @@
 	// Build the CREATE TABLE query
-	query := fmt.Sprintf("CREATE TABLE %s.%s (\n\t%s\n) ENGINE = %s",
-		schema, storageUnit, strings.Join(columns, ",\n\t"), engineSettings.engine)
+	query := fmt.Sprintf("CREATE TABLE ?.? (\n\t%s\n) ENGINE = %s",
+		strings.Join(columns, ",\n\t"), engineSettings.engine)
 
@@ -74,3 +74,3 @@
 
-	_, err = conn.ExecContext(context.Background(), query)
+	_, err = conn.ExecContext(context.Background(), query, sql.Named("schema", schema), sql.Named("storageUnit", storageUnit))
 	if err != nil {
EOF
@@ -52,4 +52,4 @@
// Build the CREATE TABLE query
query := fmt.Sprintf("CREATE TABLE %s.%s (\n\t%s\n) ENGINE = %s",
schema, storageUnit, strings.Join(columns, ",\n\t"), engineSettings.engine)
query := fmt.Sprintf("CREATE TABLE ?.? (\n\t%s\n) ENGINE = %s",
strings.Join(columns, ",\n\t"), engineSettings.engine)

@@ -74,3 +74,3 @@

_, err = conn.ExecContext(context.Background(), query)
_, err = conn.ExecContext(context.Background(), query, sql.Named("schema", schema), sql.Named("storageUnit", storageUnit))
if err != nil {
Copilot is powered by AI and may make mistakes. Always verify output.
Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
@@ -100,6 +100,6 @@
query := fmt.Sprintf("INSERT INTO %s.%s (%s) VALUES (%s)",
schema, storageUnit, strings.Join(columns, ", "), strings.Join(placeholders, ", "))

err = conn.Exec(context.Background(), query, args...)
_, err = conn.ExecContext(context.Background(), query, args...)

Check failure

Code scanning / CodeQL

Database query built from user-controlled sources High

This query depends on a
user-provided value
.
This query depends on a
user-provided value
.
This query depends on a
user-provided value
.
This query depends on a
user-provided value
.

Copilot Autofix AI 7 days ago

To fix the problem, we need to use parameterized queries or prepared statements to safely embed user-controlled data into the SQL query. This approach prevents SQL injection by ensuring that user input is treated as data rather than executable code.

In the AddRow function, we should modify the query construction to use placeholders for the schema and storageUnit parameters and pass them as arguments to the ExecContext function. This will ensure that these parameters are safely embedded into the query.

Suggested changeset 1
core/src/plugins/clickhouse/add.go

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/core/src/plugins/clickhouse/add.go b/core/src/plugins/clickhouse/add.go
--- a/core/src/plugins/clickhouse/add.go
+++ b/core/src/plugins/clickhouse/add.go
@@ -99,6 +99,6 @@
 
-	query := fmt.Sprintf("INSERT INTO %s.%s (%s) VALUES (%s)",
-		schema, storageUnit, strings.Join(columns, ", "), strings.Join(placeholders, ", "))
+	query := fmt.Sprintf("INSERT INTO ?.? (%s) VALUES (%s)",
+		strings.Join(columns, ", "), strings.Join(placeholders, ", "))
 
-	_, err = conn.ExecContext(context.Background(), query, args...)
+	_, err = conn.ExecContext(context.Background(), query, append([]interface{}{schema, storageUnit}, args...)...)
 	return err == nil, err
EOF
@@ -99,6 +99,6 @@

query := fmt.Sprintf("INSERT INTO %s.%s (%s) VALUES (%s)",
schema, storageUnit, strings.Join(columns, ", "), strings.Join(placeholders, ", "))
query := fmt.Sprintf("INSERT INTO ?.? (%s) VALUES (%s)",
strings.Join(columns, ", "), strings.Join(placeholders, ", "))

_, err = conn.ExecContext(context.Background(), query, args...)
_, err = conn.ExecContext(context.Background(), query, append([]interface{}{schema, storageUnit}, args...)...)
return err == nil, err
Copilot is powered by AI and may make mistakes. Always verify output.
Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
@@ -66,7 +66,7 @@
WHERE database = '%s'
`, schema)

rows, err := conn.Query(context.Background(), query)
rows, err := conn.QueryContext(context.Background(), query)

Check failure

Code scanning / CodeQL

Database query built from user-controlled sources High

This query depends on a
user-provided value
.
This query depends on a
user-provided value
.
This query depends on a
user-provided value
.
This query depends on a
user-provided value
.

Copilot Autofix AI 7 days ago

To fix the problem, we need to use parameterized queries instead of string concatenation to safely include the user-provided schema parameter in the SQL query. This can be achieved by using the QueryContext method with placeholders for parameters.

  • Modify the GetStorageUnits function in core/src/plugins/clickhouse/clickhouse.go to use a parameterized query.
  • Replace the fmt.Sprintf usage with a query string that includes a placeholder for the schema parameter.
  • Pass the schema parameter as an argument to the QueryContext method.
Suggested changeset 1
core/src/plugins/clickhouse/clickhouse.go

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/core/src/plugins/clickhouse/clickhouse.go b/core/src/plugins/clickhouse/clickhouse.go
--- a/core/src/plugins/clickhouse/clickhouse.go
+++ b/core/src/plugins/clickhouse/clickhouse.go
@@ -58,3 +58,3 @@
 
-	query := fmt.Sprintf(`
+	query := `
 		SELECT 
@@ -65,6 +65,6 @@
 		FROM system.tables 
-		WHERE database = '%s'
-	`, schema)
+		WHERE database = ?
+	`
 
-	rows, err := conn.QueryContext(context.Background(), query)
+	rows, err := conn.QueryContext(context.Background(), query, schema)
 	if err != nil {
EOF
@@ -58,3 +58,3 @@

query := fmt.Sprintf(`
query := `
SELECT
@@ -65,6 +65,6 @@
FROM system.tables
WHERE database = '%s'
`, schema)
WHERE database = ?
`

rows, err := conn.QueryContext(context.Background(), query)
rows, err := conn.QueryContext(context.Background(), query, schema)
if err != nil {
Copilot is powered by AI and may make mistakes. Always verify output.
Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
@@ -112,7 +112,7 @@
ORDER BY position
`, schema, tableName)

rows, err := conn.Query(context.Background(), query)
rows, err := conn.QueryContext(context.Background(), query)

Check failure

Code scanning / CodeQL

Database query built from user-controlled sources High

This query depends on a
user-provided value
.
This query depends on a
user-provided value
.
This query depends on a
user-provided value
.
This query depends on a
user-provided value
.

Copilot Autofix AI 7 days ago

To fix the problem, we need to use parameterized queries instead of string concatenation to construct the SQL query. This will ensure that user input is properly escaped and cannot be used to inject malicious SQL code.

  • Replace the fmt.Sprintf usage with parameterized queries using ? placeholders.
  • Modify the getTableSchema function to accept the schema and tableName parameters as query arguments.
  • Update the conn.QueryContext call to pass the parameters separately.
Suggested changeset 1
core/src/plugins/clickhouse/clickhouse.go

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/core/src/plugins/clickhouse/clickhouse.go b/core/src/plugins/clickhouse/clickhouse.go
--- a/core/src/plugins/clickhouse/clickhouse.go
+++ b/core/src/plugins/clickhouse/clickhouse.go
@@ -105,3 +105,3 @@
 func getTableSchema(conn *sql.DB, schema string, tableName string) ([]engine.Record, error) {
-	query := fmt.Sprintf(`
+	query := `
 		SELECT 
@@ -110,7 +110,7 @@
 		FROM system.columns
-		WHERE database = '%s' AND table = '%s'
+		WHERE database = ? AND table = ?
 		ORDER BY position
-	`, schema, tableName)
+	`
 
-	rows, err := conn.QueryContext(context.Background(), query)
+	rows, err := conn.QueryContext(context.Background(), query, schema, tableName)
 	if err != nil {
EOF
@@ -105,3 +105,3 @@
func getTableSchema(conn *sql.DB, schema string, tableName string) ([]engine.Record, error) {
query := fmt.Sprintf(`
query := `
SELECT
@@ -110,7 +110,7 @@
FROM system.columns
WHERE database = '%s' AND table = '%s'
WHERE database = ? AND table = ?
ORDER BY position
`, schema, tableName)
`

rows, err := conn.QueryContext(context.Background(), query)
rows, err := conn.QueryContext(context.Background(), query, schema, tableName)
if err != nil {
Copilot is powered by AI and may make mistakes. Always verify output.
Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
@@ -68,7 +73,7 @@
strings.Join(whereClauses, " AND "))

// Execute the query
err = conn.Exec(context.Background(), query, args...)
_, err = conn.ExecContext(context.Background(), query, args...)

Check failure

Code scanning / CodeQL

Database query built from user-controlled sources High

This query depends on a
user-provided value
.
This query depends on a
user-provided value
.
This query depends on a
user-provided value
.

Copilot Autofix AI 7 days ago

To fix the problem, we need to ensure that user-provided data is safely embedded into the SQL query. This can be achieved by using parameterized queries or prepared statements. In this case, we will modify the code to use parameterized queries for the schema and storageUnit parameters.

  1. Modify the DeleteRow function in core/src/plugins/clickhouse/delete.go to use parameterized queries for the schema and storageUnit parameters.
  2. Update the query construction to include placeholders for the schema and storageUnit parameters.
  3. Pass the schema and storageUnit parameters as arguments to the ExecContext function.
Suggested changeset 1
core/src/plugins/clickhouse/delete.go

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/core/src/plugins/clickhouse/delete.go b/core/src/plugins/clickhouse/delete.go
--- a/core/src/plugins/clickhouse/delete.go
+++ b/core/src/plugins/clickhouse/delete.go
@@ -67,10 +67,8 @@
 	// Construct the DELETE query
-	query := fmt.Sprintf(`
-		ALTER TABLE %s.%s
-		DELETE WHERE %s`,
-		schema,
-		storageUnit,
-		strings.Join(whereClauses, " AND "))
+	query := `
+		ALTER TABLE ?.? 
+		DELETE WHERE ` + strings.Join(whereClauses, " AND ")
 
 	// Execute the query
+	args = append([]interface{}{schema, storageUnit}, args...)
 	_, err = conn.ExecContext(context.Background(), query, args...)
EOF
@@ -67,10 +67,8 @@
// Construct the DELETE query
query := fmt.Sprintf(`
ALTER TABLE %s.%s
DELETE WHERE %s`,
schema,
storageUnit,
strings.Join(whereClauses, " AND "))
query := `
ALTER TABLE ?.?
DELETE WHERE ` + strings.Join(whereClauses, " AND ")

// Execute the query
args = append([]interface{}{schema, storageUnit}, args...)
_, err = conn.ExecContext(context.Background(), query, args...)
Copilot is powered by AI and may make mistakes. Always verify output.
Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
@@ -28,13 +28,16 @@
}
defer conn.Close()

rows, err := conn.Query(context.Background(), query, params)
rows, err := conn.QueryContext(context.Background(), query, params)

Check failure

Code scanning / CodeQL

Database query built from user-controlled sources High

This query depends on a
user-provided value
.
This query depends on a
user-provided value
.
This query depends on a
user-provided value
.
This query depends on a
user-provided value
.
This query depends on a
user-provided value
.
This query depends on a
user-provided value
.
This query depends on a
user-provided value
.
This query depends on a
user-provided value
.

Copilot Autofix AI 7 days ago

To fix the problem, we need to use parameterized queries instead of directly embedding user-controlled values into the SQL query string. This can be achieved by using placeholders (?) in the query string and passing the actual values as arguments to the QueryContext method.

  1. Modify the GetRows function to use parameterized queries.
  2. Update the executeQuery function to accept additional parameters for the query placeholders.
  3. Ensure that the RawExecute function also uses parameterized queries if applicable.
Suggested changeset 1
core/src/plugins/clickhouse/query.go

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/core/src/plugins/clickhouse/query.go b/core/src/plugins/clickhouse/query.go
--- a/core/src/plugins/clickhouse/query.go
+++ b/core/src/plugins/clickhouse/query.go
@@ -10,9 +10,6 @@
 func (p *ClickHousePlugin) GetRows(config *engine.PluginConfig, schema string, storageUnit string, where string, pageSize int, pageOffset int) (*engine.GetRowsResult, error) {
-	query := fmt.Sprintf("SELECT * FROM %s.%s", schema, storageUnit)
-	if where != "" {
-		query += " WHERE " + where
-	}
-	query += fmt.Sprintf(" LIMIT %d OFFSET %d", pageSize, pageOffset)
+	query := "SELECT * FROM ?.? WHERE ? LIMIT ? OFFSET ?"
+	params := []interface{}{schema, storageUnit, where, pageSize, pageOffset}
 
-	return p.executeQuery(config, query)
+	return p.executeQuery(config, query, params...)
 }
@@ -30,3 +27,3 @@
 
-	rows, err := conn.QueryContext(context.Background(), query, params)
+	rows, err := conn.QueryContext(context.Background(), query, params...)
 	if err != nil {
EOF
@@ -10,9 +10,6 @@
func (p *ClickHousePlugin) GetRows(config *engine.PluginConfig, schema string, storageUnit string, where string, pageSize int, pageOffset int) (*engine.GetRowsResult, error) {
query := fmt.Sprintf("SELECT * FROM %s.%s", schema, storageUnit)
if where != "" {
query += " WHERE " + where
}
query += fmt.Sprintf(" LIMIT %d OFFSET %d", pageSize, pageOffset)
query := "SELECT * FROM ?.? WHERE ? LIMIT ? OFFSET ?"
params := []interface{}{schema, storageUnit, where, pageSize, pageOffset}

return p.executeQuery(config, query)
return p.executeQuery(config, query, params...)
}
@@ -30,3 +27,3 @@

rows, err := conn.QueryContext(context.Background(), query, params)
rows, err := conn.QueryContext(context.Background(), query, params...)
if err != nil {
Copilot is powered by AI and may make mistakes. Always verify output.
Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
@@ -99,7 +104,7 @@
strings.Join(setClauses, ", "),
strings.Join(whereClauses, " AND "))

err = conn.Exec(context.Background(), query, args...)
_, err = conn.ExecContext(context.Background(), query, args...)

Check failure

Code scanning / CodeQL

Database query built from user-controlled sources High

This query depends on a
user-provided value
.
This query depends on a
user-provided value
.
This query depends on a
user-provided value
.

Copilot Autofix AI 7 days ago

To fix the problem, we need to ensure that the schema parameter is safely embedded into the SQL query. This can be achieved by using parameterized queries or prepared statements, which prevent SQL injection by treating user input as data rather than executable code.

In this specific case, we can use the sql.Named function to safely include the schema parameter in the query. This approach ensures that the schema value is properly escaped and treated as a parameter rather than part of the SQL command.

Suggested changeset 1
core/src/plugins/clickhouse/update.go

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/core/src/plugins/clickhouse/update.go b/core/src/plugins/clickhouse/update.go
--- a/core/src/plugins/clickhouse/update.go
+++ b/core/src/plugins/clickhouse/update.go
@@ -98,9 +98,8 @@
 
-	query := fmt.Sprintf(`
-		ALTER TABLE %s.%s
-		UPDATE %s
-		WHERE %s`,
-		schema, storageUnit,
-		strings.Join(setClauses, ", "),
-		strings.Join(whereClauses, " AND "))
+	query := `
+		ALTER TABLE ?.? 
+		UPDATE ? 
+		WHERE ?`
+
+	args = append([]interface{}{schema, storageUnit, strings.Join(setClauses, ", "), strings.Join(whereClauses, " AND ")}, args...)
 
EOF
@@ -98,9 +98,8 @@

query := fmt.Sprintf(`
ALTER TABLE %s.%s
UPDATE %s
WHERE %s`,
schema, storageUnit,
strings.Join(setClauses, ", "),
strings.Join(whereClauses, " AND "))
query := `
ALTER TABLE ?.?
UPDATE ?
WHERE ?`

args = append([]interface{}{schema, storageUnit, strings.Join(setClauses, ", "), strings.Join(whereClauses, " AND ")}, args...)

Copilot is powered by AI and may make mistakes. Always verify output.
Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
@@ -18,7 +18,7 @@
WHERE database = '%s' AND table = '%s'`,
schema, table)

rows, err := conn.Query(context.Background(), query)
rows, err := conn.QueryContext(context.Background(), query)

Check failure

Code scanning / CodeQL

Database query built from user-controlled sources High

This query depends on a
user-provided value
.
This query depends on a
user-provided value
.
This query depends on a
user-provided value
.
This query depends on a
user-provided value
.
This query depends on a
user-provided value
.

Copilot Autofix AI 11 days ago

To fix the problem, we need to use parameterized queries instead of string concatenation to construct the SQL query. This will ensure that user input is properly escaped and cannot be used to inject malicious SQL code.

  • Replace the fmt.Sprintf call with a parameterized query using placeholders.
  • Use the QueryContext method with the appropriate arguments to pass the user input as parameters to the query.
Suggested changeset 1
core/src/plugins/clickhouse/utils.go

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/core/src/plugins/clickhouse/utils.go b/core/src/plugins/clickhouse/utils.go
--- a/core/src/plugins/clickhouse/utils.go
+++ b/core/src/plugins/clickhouse/utils.go
@@ -12,3 +12,3 @@
 func getColumnTypes(conn *sql.DB, schema string, table string) (map[string]string, error) {
-	query := fmt.Sprintf(`
+	query := `
 		SELECT 
@@ -17,6 +17,5 @@
 		FROM system.columns
-		WHERE database = '%s' AND table = '%s'`,
-		schema, table)
+		WHERE database = ? AND table = ?`
 
-	rows, err := conn.QueryContext(context.Background(), query)
+	rows, err := conn.QueryContext(context.Background(), query, schema, table)
 	if err != nil {
EOF
@@ -12,3 +12,3 @@
func getColumnTypes(conn *sql.DB, schema string, table string) (map[string]string, error) {
query := fmt.Sprintf(`
query := `
SELECT
@@ -17,6 +17,5 @@
FROM system.columns
WHERE database = '%s' AND table = '%s'`,
schema, table)
WHERE database = ? AND table = ?`

rows, err := conn.QueryContext(context.Background(), query)
rows, err := conn.QueryContext(context.Background(), query, schema, table)
if err != nil {
Copilot is powered by AI and may make mistakes. Always verify output.
Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
@modelorona modelorona changed the title Release - Fix path traversal bug for sqlite and add several clickhouse options Release - Fix path traversal bug for sqlite, new clickhouse options, and support for OpenAI-like URLs Jan 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants