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
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
898d894
add openai compatible provider
Dec 2, 2024
b12bc69
Merge branch 'clidey:main' into main
learningpro Dec 2, 2024
15fa9ca
Merge branch 'main' into main
learningpro Dec 20, 2024
95026e8
add additional options for clickhouse support, HTTP protocol, TLS mod…
Slach Dec 21, 2024
1411fcf
Merge pull request #300 from Slach/main
hkdeman Jan 8, 2025
b994967
Merge pull request #252 from learningpro/main
hkdeman Jan 8, 2025
27f106b
fix variant A and B for path traversal
modelorona Jan 23, 2025
cb5b9bf
remove string processing code
modelorona Jan 24, 2025
cfda05a
update directory to end with slash
modelorona Jan 25, 2025
9c15d79
initial fix for mysql to use the driver Config object to build the ds…
modelorona Jan 25, 2025
cb871a0
change to hostPath check to account for length
modelorona Jan 25, 2025
380544c
removed the hostPath for now. removed & from collation before passing…
modelorona Jan 25, 2025
9e8669a
add back func for reading in params behind isProfile guard
modelorona Jan 25, 2025
903c223
postgres dsn builder surrounds all params with single quotes now to t…
modelorona Jan 25, 2025
f2d6de1
redis addr built using net.JoinHostPort
modelorona Jan 25, 2025
dd94d97
modify mongodb to connect using clientOptions
modelorona Jan 25, 2025
520d862
query escape for elasticsearch
modelorona Jan 25, 2025
33a56d1
disable clickhouse sslmode as it's not fully complete. update elastic…
modelorona Jan 25, 2025
3f6fcab
Update issue templates
modelorona Jan 26, 2025
547336a
Merge commit from fork
modelorona Jan 27, 2025
0e75ff3
parse port as num and fail otherwise, remove collation option from fr…
modelorona Jan 27, 2025
6f1ebf3
update clickhouse config
modelorona Jan 27, 2025
2d47a83
update postgres handling to escape all single quotes to avoid jumping…
modelorona Jan 27, 2025
5978412
fix clickhouse setup to allow for both port 9000 (tcp) and port 8123 …
modelorona Jan 27, 2025
8d67b76
Merge commit from fork
modelorona Jan 27, 2025
f67f843
feat(core,frontend): add alias logic
hkdeman Jan 28, 2025
76e0cad
Merge pull request #331 from clidey/hk/issues/alias
hkdeman Jan 28, 2025
e2f0ed9
feat(frontend): fix table header logic to have unique ids
hkdeman Jan 28, 2025
114522f
feat(frontend): fix up undefined
hkdeman Jan 28, 2025
410561a
Merge pull request #332 from clidey/hk/issues/scratchpad-wrong-columns
hkdeman Jan 28, 2025
bef215f
feat(frontend): replace monaco editor with code mirror for offline pa…
hkdeman Jan 28, 2025
df37d60
feat(editor): fix theming
hkdeman Jan 28, 2025
e7d8228
feat(frontend): fix markdown library issue
hkdeman Jan 28, 2025
c27f796
Merge pull request #333 from clidey/hk/issues/switch-to-code-mirror
hkdeman Jan 28, 2025
46a7956
feat(frontend): add loader and loading states
hkdeman Jan 28, 2025
e19fe5a
Revert "feat(frontend): add loader and loading states"
hkdeman Jan 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: Bug report
about: Create a report to help us improve
about: Create a report to help us improve WhoDB.
title: "[BUG] - {your title here}"
labels: bug
assignees: ''
Expand All @@ -24,15 +24,16 @@ A clear and concise description of what you expected to happen.
If applicable, add screenshots to help explain your problem.

**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
- OS that WhoDB is running on: [e.g. Ubuntu]
- How you're running WhoDB: [e.g, Docker, exe, manually]
- Browser: [e.g. chrome, safari]
- Version: [e.g. 22]

**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
- Browser: [e.g. stock browser, safari]
- Version: [e.g. 22]

**Additional context**
Add any other context about the problem here.
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: Feature request
about: Suggest an idea for this project
about: Suggest an idea for this project.
title: "[FR] - {your title here}"
labels: enhancement
assignees: ''
Expand Down
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,17 @@ Get up and running with WhoDB quickly using Docker:
docker run -it -p 8080:8080 clidey/whodb
```


To run WhoDB with an OpenAI compatible service, you should assign some environments.
```sh
docker run -it -e USE_CUSTOM_MODELS=1 -e CUSTOM_MODELS=gpt-4o,gpt-3.5,others -e OPENAI_BASE_URL=http://your_base_url/v1 -p 8080:8080 clidey/whodb
```

If you are using a remote Ollama server, please start Docker with Ollama Environments like this:
```sh
docker run -it -e WHODB_OLLAMA_HOST=YOUR_OLLAMA_HOST -e WHODB_OLLAMA_PORT=YOUR_OLLAMA_PORT -p 8080:8080 clidey/whodb
```


Or, use Docker Compose:
```sh
version: "3.8"
Expand Down
63 changes: 58 additions & 5 deletions core/graph/generated.go

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

5 changes: 4 additions & 1 deletion core/graph/model/models_gen.go

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

2 changes: 2 additions & 0 deletions core/graph/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ enum DatabaseType {
Redis,
ElasticSearch,
MariaDB,
ClickHouse,
}

type Column {
Expand Down Expand Up @@ -78,6 +79,7 @@ input LoginProfileInput {
}

type LoginProfile {
Alias: String
Id: String!
Type: DatabaseType!
Database: String
Expand Down
12 changes: 9 additions & 3 deletions core/graph/schema.resolvers.go

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

1 change: 1 addition & 0 deletions core/src/engine/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type Credentials struct {
Database string
Advanced []Record
AccessToken *string
IsProfile bool
}

type ExternalModel struct {
Expand Down
4 changes: 3 additions & 1 deletion core/src/env/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,16 @@ func GetClideyQuickContainerImage() string {
}

type DatabaseCredentials struct {
Alias string `json:"alias"`
Hostname string `json:"host"`
Username string `json:"user"`
Password string `json:"password"`
Database string `json:"database"`
Port string `json:"port"`
Config map[string]string `json:"config"`

Type string
IsProfile bool
Type string
}

func GetDefaultDatabaseCredentials(databaseType string) []DatabaseCredentials {
Expand Down
5 changes: 2 additions & 3 deletions core/src/llm/chatgpt_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"strings"
)

const chatGPTEndpoint = "https://api.openai.com/v1"

func prepareChatGPTRequest(c *LLMClient, prompt string, model LLMModel, receiverChan *chan string) (string, []byte, map[string]string, error) {
requestBody, err := json.Marshal(map[string]interface{}{
Expand All @@ -20,7 +19,7 @@ func prepareChatGPTRequest(c *LLMClient, prompt string, model LLMModel, receiver
if err != nil {
return "", nil, nil, err
}
url := fmt.Sprintf("%v/chat/completions", chatGPTEndpoint)
url := fmt.Sprintf("%v/chat/completions", getOpenAICompatibleBaseURL())
headers := map[string]string{
"Authorization": fmt.Sprintf("Bearer %s", c.APIKey),
"Content-Type": "application/json",
Expand All @@ -29,7 +28,7 @@ func prepareChatGPTRequest(c *LLMClient, prompt string, model LLMModel, receiver
}

func prepareChatGPTModelsRequest(apiKey string) (string, map[string]string) {
url := fmt.Sprintf("%v/models", chatGPTEndpoint)
url := fmt.Sprintf("%v/models", getOpenAICompatibleBaseURL())
headers := map[string]string{
"Authorization": fmt.Sprintf("Bearer %s", apiKey),
"Content-Type": "application/json",
Expand Down
31 changes: 30 additions & 1 deletion core/src/llm/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ package llm

import (
"fmt"

"strings"
"os"
"github.com/clidey/whodb/core/src/common"
"github.com/clidey/whodb/core/src/env"
)
Expand All @@ -24,3 +25,31 @@ func getOllamaEndpoint() string {

return fmt.Sprintf("http://%v:%v/api", host, port)
}

func getOpenAICompatibleBaseURL() string {
defaultBaseURL := "https://api.openai.com/v1"
baseURL := os.Getenv("OPENAI_BASE_URL")
if baseURL == "" {
baseURL = defaultBaseURL
}
return baseURL
}

func getCustomModels() ([]string, error) {
modelsStr := os.Getenv("CUSTOM_MODELS")
if modelsStr == "" {
return []string{}, nil
}

models := strings.Split(modelsStr, ",")

for i := range models {
models[i] = strings.TrimSpace(models[i])
}
return models, nil
}

func ShouldUseCustomModels() bool {
useCustomModels := os.Getenv("USE_CUSTOM_MODELS")
return useCustomModels == "1"
}
3 changes: 3 additions & 0 deletions core/src/llm/llm_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ func (c *LLMClient) GetSupportedModels() ([]string, error) {
url, headers = prepareOllamaModelsRequest()
case ChatGPT_LLMType:
url, headers = prepareChatGPTModelsRequest(c.APIKey)
if ShouldUseCustomModels() {
return getCustomModels()
}
case Anthropic_LLMType:
return getAnthropicModels(c.APIKey)
default:
Expand Down
4 changes: 2 additions & 2 deletions core/src/plugins/clickhouse/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
if err != nil {
return false, fmt.Errorf("failed to create table: %w (query: %s)", err, query)
}
Expand Down Expand Up @@ -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
return err == nil, err
}
Loading
Loading