fix(subsonic): validate JSONP callback parameter

Added validation to ensure the JSONP callback parameter is a valid
JavaScript identifier before reflecting it into the response. Invalid
callbacks now return a JSON error response instead. This prevents
malicious input from being injected into the response body via the
callback parameter.
This commit is contained in:
Deluan
2026-02-08 10:33:46 -05:00
parent a704e86ac1
commit 0a4722802a
2 changed files with 56 additions and 1 deletions
+13 -1
View File
@@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"net/http"
"regexp"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
@@ -26,6 +27,8 @@ import (
const Version = "1.16.1"
var validJSIdentifier = regexp.MustCompile(`^[a-zA-Z_$][a-zA-Z0-9_$.]*$`)
type handler = func(*http.Request) (*responses.Subsonic, error)
type handlerRaw = func(http.ResponseWriter, *http.Request) (*responses.Subsonic, error)
@@ -315,8 +318,17 @@ func sendResponse(w http.ResponseWriter, r *http.Request, payload *responses.Sub
wrapper := &responses.JsonWrapper{Subsonic: *payload}
response, err = json.Marshal(wrapper)
case "jsonp":
w.Header().Set("Content-Type", "application/javascript")
callback, _ := p.String("callback")
if !validJSIdentifier.MatchString(callback) {
log.Warn(r.Context(), "Invalid JSONP callback parameter", "callback", callback)
w.Header().Set("Content-Type", "application/json")
errResp := newResponse()
errResp.Status = responses.StatusFailed
errResp.Error = &responses.Error{Code: responses.ErrorGeneric, Message: "invalid callback parameter"}
response, _ = json.Marshal(responses.JsonWrapper{Subsonic: *errResp})
break
}
w.Header().Set("Content-Type", "application/javascript")
wrapper := &responses.JsonWrapper{Subsonic: *payload}
response, err = json.Marshal(wrapper)
response = fmt.Appendf(nil, "%s(%s)", callback, response)