mirror of
https://github.com/bitechdev/ResolveSpec.git
synced 2026-01-16 07:54:25 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c12c045db1 |
@@ -237,15 +237,29 @@ func (v *ColumnValidator) FilterRequestOptions(options RequestOptions) RequestOp
|
|||||||
for _, sort := range options.Sort {
|
for _, sort := range options.Sort {
|
||||||
if v.IsValidColumn(sort.Column) {
|
if v.IsValidColumn(sort.Column) {
|
||||||
validSorts = append(validSorts, sort)
|
validSorts = append(validSorts, sort)
|
||||||
} else if strings.HasPrefix(sort.Column, "(") && strings.HasSuffix(sort.Column, ")") {
|
|
||||||
// Allow sort by expression/subquery, but validate for security
|
|
||||||
if IsSafeSortExpression(sort.Column) {
|
|
||||||
validSorts = append(validSorts, sort)
|
|
||||||
} else {
|
|
||||||
logger.Warn("Unsafe sort expression '%s' removed", sort.Column)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
logger.Warn("Invalid column in sort '%s' removed", sort.Column)
|
foundJoin := false
|
||||||
|
for _, j := range options.JoinAliases {
|
||||||
|
if strings.Contains(sort.Column, j) {
|
||||||
|
foundJoin = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if foundJoin {
|
||||||
|
validSorts = append(validSorts, sort)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(sort.Column, "(") && strings.HasSuffix(sort.Column, ")") {
|
||||||
|
// Allow sort by expression/subquery, but validate for security
|
||||||
|
if IsSafeSortExpression(sort.Column) {
|
||||||
|
validSorts = append(validSorts, sort)
|
||||||
|
} else {
|
||||||
|
logger.Warn("Unsafe sort expression '%s' removed", sort.Column)
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
logger.Warn("Invalid column in sort '%s' removed", sort.Column)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
filtered.Sort = validSorts
|
filtered.Sort = validSorts
|
||||||
@@ -291,6 +305,9 @@ func (v *ColumnValidator) FilterRequestOptions(options RequestOptions) RequestOp
|
|||||||
}
|
}
|
||||||
filtered.Preload = validPreloads
|
filtered.Preload = validPreloads
|
||||||
|
|
||||||
|
// Clear JoinAliases - this is an internal validation field and should not be persisted
|
||||||
|
filtered.JoinAliases = nil
|
||||||
|
|
||||||
return filtered
|
return filtered
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -362,6 +362,29 @@ func TestFilterRequestOptions(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFilterRequestOptions_ClearsJoinAliases(t *testing.T) {
|
||||||
|
model := TestModel{}
|
||||||
|
validator := NewColumnValidator(model)
|
||||||
|
|
||||||
|
options := RequestOptions{
|
||||||
|
Columns: []string{"id", "name"},
|
||||||
|
// Set JoinAliases - this should be cleared by FilterRequestOptions
|
||||||
|
JoinAliases: []string{"d", "u", "r"},
|
||||||
|
}
|
||||||
|
|
||||||
|
filtered := validator.FilterRequestOptions(options)
|
||||||
|
|
||||||
|
// Verify that JoinAliases was cleared (internal field should not persist)
|
||||||
|
if filtered.JoinAliases != nil {
|
||||||
|
t.Errorf("Expected JoinAliases to be nil after filtering, got %v", filtered.JoinAliases)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that other fields are still properly filtered
|
||||||
|
if len(filtered.Columns) != 2 {
|
||||||
|
t.Errorf("Expected 2 columns, got %d", len(filtered.Columns))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestIsSafeSortExpression(t *testing.T) {
|
func TestIsSafeSortExpression(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
|||||||
Reference in New Issue
Block a user