feat(backend): Add query guardrails to prevent potential issues (#2149)

## Summary

Implements query guardrails in the backend to prevent execution of
expensive or malformed queries that could impact customer environments.

Part of https://github.com/grafana/oss-big-tent-squad/issues/127

## Changes

### New guardrails added:

1. **Item ID validation** (`queryItemIdData`)
   - Validates that item IDs are non-empty
   - Validates that item IDs contain only numeric values

2. **Time range validation** (`QueryData`)
   - Validates that `From` timestamp is before `To` timestamp

3. **API method allowlist** (`ZabbixAPIHandler`)
- Only allows Zabbix API methods defined in the frontend type
`zabbixMethodName`
   - Blocks any write/delete/update operations not in the allowlist

### New files:
- `pkg/datasource/guardrails.go` - Validation functions and error
definitions
- `pkg/datasource/guardrails_test.go` - Unit tests for all validation
functions

### Modified files:
- `pkg/datasource/datasource.go` - Added time range validation
- `pkg/datasource/zabbix.go` - Added item ID validation  
- `pkg/datasource/resource_handler.go` - Added API method validation

## Reasoning
- Allowed functions might be unnecessary as we've already prevent using
those in
[types.ts](https://github.com/grafana/grafana-zabbix/blob/main/src/datasource/zabbix/types.ts#L1-L23)
but it's nice to be cautious.
- itemid and time validation is just for sanity. 
- Time range validation will be necessary in the future to warn user
agains running expensive queries.
This commit is contained in:
ismail simsek
2025-12-29 18:57:17 +01:00
committed by GitHub
parent 3e626d3aa5
commit 04fca562b0
5 changed files with 456 additions and 0 deletions

View File

@@ -78,6 +78,11 @@ func (ds *ZabbixDatasourceInstance) queryNumericItems(ctx context.Context, query
}
func (ds *ZabbixDatasourceInstance) queryItemIdData(ctx context.Context, query *QueryModel) ([]*data.Frame, error) {
// Validate itemids before processing
if err := ValidateItemIDs(query.ItemIDs); err != nil {
return nil, err
}
itemids := strings.Split(query.ItemIDs, ",")
for i, id := range itemids {
itemids[i] = strings.Trim(id, " ")