fix(funcspec): refine filter application logic for SQL queries

* update filter checks to only consider SELECT list
* add test for function parameters not matching filters
This commit is contained in:
Hein
2026-05-15 14:28:12 +02:00
parent ae9e06c98b
commit 1ebe0d7ac3
2 changed files with 70 additions and 3 deletions

View File

@@ -729,9 +729,10 @@ func (h *Handler) mergeQueryParams(r *http.Request, sqlquery string, variables m
propQry[parmk] = val
}
// Apply filters if allowed — check against string-literal-stripped SQL to avoid
// matching column names that only appear inside quoted arguments (e.g. JSON strings)
if allowFilter && len(parmk) > 1 && strings.Contains(strings.ToLower(sqlStripStringLiterals(sqlquery)), strings.ToLower(parmk)) {
// Apply filters if allowed — check only the SELECT list to avoid matching function
// parameters in the FROM clause (e.g. [p_rid_doctype] in a set-returning function call)
// or names inside quoted string arguments.
if allowFilter && len(parmk) > 1 && strings.Contains(sqlSelectList(sqlStripStringLiterals(sqlquery)), strings.ToLower(parmk)) {
if len(parmv) > 1 {
// Sanitize each value in the IN clause with appropriate quoting
sanitizedValues := make([]string, len(parmv))
@@ -847,6 +848,18 @@ func sqlStripStringLiterals(sql string) string {
return re.ReplaceAllString(sql, "''")
}
// sqlSelectList returns the column list portion of a SELECT query (between SELECT and FROM).
// Returns the full query lowercased if no clear SELECT…FROM boundary is found.
func sqlSelectList(sql string) string {
lower := strings.ToLower(sql)
selectPos := strings.Index(lower, "select ")
fromPos := strings.Index(lower, " from ")
if selectPos < 0 || fromPos <= selectPos {
return lower
}
return lower[selectPos+7 : fromPos]
}
// replaceMetaVariables replaces meta variables like [rid_user], [user], etc. in the SQL query
func (h *Handler) replaceMetaVariables(sqlquery string, r *http.Request, userCtx *security.UserContext, metainfo map[string]interface{}, variables map[string]interface{}) string {
if strings.Contains(sqlquery, "[p_meta_default]") {