Skip to content

Security: Pervasive cross-team IDOR - GraphQL resolvers lack team/project membership validation #206

@lighthousekeeper1212

Description

@lighthousekeeper1212

Summary

All GraphQL mutation resolvers operate on resources (tasks, checklists, teams, projects) by ID without verifying the authenticated user has access to the team or project that owns the resource.

Details

The authentication middleware (internal/route/route.go:118) only verifies the user is logged in, not that they belong to the relevant team/project. The GetProjectRoles() function exists in internal/graph/graph.go:215 but is rarely called by resolvers.

Example 1 - Add anyone to any team (internal/graph/team.resolvers.go:18):

func (r *mutationResolver) CreateTeamMember(ctx context.Context, input CreateTeamMember) {
    // Takes input.TeamID directly - no membership validation
    r.Repository.CreateTeamMember(ctx, db.CreateTeamMemberParams{
        TeamID: input.TeamID, UserID: input.UserID, ...})
}

Example 2 - Modify any task (internal/graph/task.resolvers.go:23):

func (r *mutationResolver) CreateTaskChecklist(ctx context.Context, input CreateTaskChecklist) {
    r.Repository.CreateTaskChecklist(ctx, db.CreateTaskChecklistParams{
        TaskID: input.TaskID, // No project/team check
    })
}

This pattern extends across all resolvers: task CRUD, checklist operations, team member management, label operations, etc.

Impact

Any authenticated user can add themselves to any team, escalate roles, create/modify/delete tasks across teams, and access all project data.

Suggested Fix

Add project/team membership validation to each resolver using the existing GetProjectRoles():

role, err := GetProjectRoles(ctx, r.Repository, projectID)
if err != nil {
    return nil, errors.New("unauthorized")
}

CWE-639: Authorization Bypass Through User-Controlled Key

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions