-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
Summary
Several integration sub-resource database queries in db/sql/integration.go accept projectID and integrationID parameters but do not use them in the SQL WHERE clause, querying only by the sub-resource's own ID. This means the project scoping enforced by the middleware chain is not reflected at the database layer.
Affected Functions
1. GetIntegrationExtractValue (line ~204)
func (d *SqlDb) GetIntegrationExtractValue(projectID int, valueID int, integrationID int) (value db.IntegrationExtractValue, err error) {
query, args, err := squirrel.Select("v.*").
From("project__integration_extract_value as v").
Where(squirrel.Eq{"id": valueID}). // only filters by valueID
OrderBy("v.id").
ToSql()Both projectID and integrationID are received but unused.
2. GetIntegrationMatcher (line ~295)
Same pattern — queries WHERE id = matcherID only, ignoring projectID and integrationID.
3. UpdateIntegrationExtractValue (line ~237)
_, err = d.exec(
"update project__integration_extract_value set ... where `id`=?",
...
integrationExtractValue.ID)Updates by ID only without checking the value belongs to the expected integration.
4. GetIntegrationMatchers (line ~279)
Queries by integration_id only without project scoping.
Secure Pattern for Comparison
The parent GetIntegration function correctly scopes by project:
func (d *SqlDb) GetIntegration(projectID int, integrationID int) (integration db.Integration, err error) {
err = d.getObject(projectID, db.IntegrationProps, integrationID, &integration)Similarly, DeleteIntegrationExtractValue uses deleteObjectByReferencedID which validates the integration_id relationship.
Impact
A user with access to Project A could read or modify integration extract values and matchers belonging to Project B by guessing or enumerating the sequential integer IDs in API requests like:
GET /api/project/{projectA_id}/integrations/{integrationA_id}/values/{valueFromProjectB_id}PUT /api/project/{projectA_id}/integrations/{integrationA_id}/matchers/{matcherFromProjectB_id}
The IntegrationMiddleware validates that the integration belongs to the project, but the sub-resource queries don't validate that the value/matcher belongs to the integration.
Suggested Fix
Add integrationID filtering to all sub-resource queries:
// GetIntegrationExtractValue - add integration_id check
Where(squirrel.Eq{"id": valueID, "integration_id": integrationID}).
// GetIntegrationMatcher - add integration_id check
Where(squirrel.Eq{"id": matcherID, "integration_id": integrationID}).
// UpdateIntegrationExtractValue - add integration_id check
"... where integration_id=? AND `id`=?"
// GetIntegrationMatchers - add project scoping via join or sub-queryThis is a 4-line fix that brings these queries in line with the secure patterns already used elsewhere in the codebase.
Environment
- Version: Latest (main branch as of Feb 2026)
- File:
db/sql/integration.go - 8 API endpoints affected across values and matchers CRUD operations