Add checks for deployment model name

This commit is contained in:
Kunal Karmakar 2026-03-12 16:00:09 +00:00
parent 577796ff13
commit 4101111df9
2 changed files with 34 additions and 3 deletions

View file

@ -6,6 +6,7 @@ import (
"encoding/json"
"fmt"
"net/http"
"net/url"
"strings"
"time"
@ -87,9 +88,13 @@ func (p *Provider) Chat(
// model is the deployment name for Azure OpenAI
deployment := model
// Build Azure-specific URL: {base}/openai/deployments/{deployment}/chat/completions?api-version=...
requestURL := fmt.Sprintf("%s/openai/deployments/%s/chat/completions?api-version=%s",
p.apiBase, deployment, azureAPIVersion)
// Build Azure-specific URL safely using url.JoinPath and query encoding
// to prevent path traversal or query injection via deployment names.
base, err := url.JoinPath(p.apiBase, "openai/deployments", deployment, "chat/completions")
if err != nil {
return nil, fmt.Errorf("failed to build Azure request URL: %w", err)
}
requestURL := base + "?api-version=" + azureAPIVersion
// Build request body — no "model" field (Azure infers from deployment URL)
requestBody := map[string]any{

View file

@ -204,3 +204,29 @@ func TestProvider_AzureNewProviderWithTimeout(t *testing.T) {
t.Errorf("timeout = %v, want %v", p.httpClient.Timeout, 180*time.Second)
}
}
func TestProviderChat_AzureDeploymentNameEscaped(t *testing.T) {
var capturedPath string
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
capturedPath = r.URL.RawPath // use RawPath to see percent-encoding
if capturedPath == "" {
capturedPath = r.URL.Path
}
writeValidResponse(w)
}))
defer server.Close()
p := NewProvider("test-key", server.URL, "")
// Deployment name with characters that could cause path injection
_, err := p.Chat(t.Context(), []Message{{Role: "user", Content: "hi"}}, nil, "my deploy/../../admin", nil)
if err != nil {
t.Fatalf("Chat() error = %v", err)
}
// The slash and special chars in the deployment name must be escaped, not treated as path separators
if capturedPath == "/openai/deployments/my deploy/../../admin/chat/completions" {
t.Fatal("deployment name was interpolated without escaping — path injection possible")
}
}