From c120b49529f9ef5587973b02937b846f0edb57f6 Mon Sep 17 00:00:00 2001 From: Hein Date: Mon, 8 Jun 2026 15:13:58 +0200 Subject: [PATCH] fix(router): prevent HTML escaping in JSON responses fix(sql_helpers): avoid prefix extraction in subqueries --- pkg/common/adapters/router/mux.go | 4 +++- pkg/common/interfaces.go | 4 +++- pkg/common/sql_helpers.go | 9 +++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/pkg/common/adapters/router/mux.go b/pkg/common/adapters/router/mux.go index 4ace587..fb686e0 100644 --- a/pkg/common/adapters/router/mux.go +++ b/pkg/common/adapters/router/mux.go @@ -174,7 +174,9 @@ func (h *HTTPResponseWriter) Write(data []byte) (int, error) { func (h *HTTPResponseWriter) WriteJSON(data interface{}) error { h.SetHeader("Content-Type", "application/json") - return json.NewEncoder(h.resp).Encode(data) + enc := json.NewEncoder(h.resp) + enc.SetEscapeHTML(false) + return enc.Encode(data) } // UnderlyingResponseWriter returns the underlying http.ResponseWriter diff --git a/pkg/common/interfaces.go b/pkg/common/interfaces.go index 52991dc..83cd3dc 100644 --- a/pkg/common/interfaces.go +++ b/pkg/common/interfaces.go @@ -178,7 +178,9 @@ func (s *StandardResponseWriter) Write(data []byte) (int, error) { func (s *StandardResponseWriter) WriteJSON(data interface{}) error { s.SetHeader("Content-Type", "application/json") - return json.NewEncoder(s.w).Encode(data) + enc := json.NewEncoder(s.w) + enc.SetEscapeHTML(false) + return enc.Encode(data) } func (s *StandardResponseWriter) UnderlyingResponseWriter() http.ResponseWriter { diff --git a/pkg/common/sql_helpers.go b/pkg/common/sql_helpers.go index 294ebf7..47305de 100644 --- a/pkg/common/sql_helpers.go +++ b/pkg/common/sql_helpers.go @@ -614,6 +614,15 @@ func extractTableAndColumn(cond string) (table string, column string) { // Remove any quotes columnRef = strings.Trim(columnRef, "`\"'") + // If the left side is a parenthesized subquery (starts with '(' and contains SQL keywords), + // don't attempt prefix extraction from inside it. + if len(columnRef) > 0 && columnRef[0] == '(' { + lowerRef := strings.ToLower(columnRef) + if strings.Contains(lowerRef, "select ") || strings.Contains(lowerRef, " from ") || strings.Contains(lowerRef, " where ") { + return "", "" + } + } + // Check if there's a function call (contains opening parenthesis) openParenIdx := strings.Index(columnRef, "(")