VYPR
High severityNVD Advisory· Published Mar 6, 2024· Updated Aug 2, 2024

`GetRepositoryByName`, `DeleteRepositoryByName` and `GetArtifactByName` allow access of arbitrary repositories in Minder by any authenticated user

CVE-2024-27916

Description

Minder is a software supply chain security platform. Prior to version 0.0.33, a Minder user can use the endpoints GetRepositoryByName, DeleteRepositoryByName, and GetArtifactByName to access any repository in the database, irrespective of who owns the repo and any permissions present. The database query checks by repo owner, repo name and provider name (which is always github). These query values are not distinct for the particular user - as long as the user has valid credentials and a provider, they can set the repo owner/name to any value they want and the server will return information on this repo. Version 0.0.33 contains a patch for this issue.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/stacklok/minderGo
< 0.0.330.0.33

Affected products

1

Patches

1
45750b4e9fb2

Merge pull request from GHSA-v627-69v2-xx37

https://github.com/stacklok/minderDon BrowneMar 4, 2024via ghsa
5 files changed · +33 11
  • database/query/repositories.sql+1 1 modified
    @@ -20,7 +20,7 @@ SELECT * FROM repositories WHERE id = $1;
     SELECT * FROM repositories WHERE repo_id = $1;
     
     -- name: GetRepositoryByRepoName :one
    -SELECT * FROM repositories WHERE provider = $1 AND repo_owner = $2 AND repo_name = $3;
    +SELECT * FROM repositories WHERE provider = $1 AND repo_owner = $2 AND repo_name = $3 AND project_id = $4;
     
     -- name: GetRepositoryByIDAndProject :one
     SELECT * FROM repositories WHERE provider = $1 AND repo_id = $2 AND project_id = $3;
    
  • internal/controlplane/handlers_artifacts.go+4 0 modified
    @@ -71,10 +71,14 @@ func (s *Server) GetArtifactByName(ctx context.Context, in *pb.GetArtifactByName
     		return nil, util.UserVisibleError(codes.InvalidArgument, "invalid artifact name user repoOwner/repoName/artifactName")
     	}
     
    +	entityCtx := engine.EntityFromContext(ctx)
    +	projectID := entityCtx.Project.ID
    +
     	repo, err := s.store.GetRepositoryByRepoName(ctx, db.GetRepositoryByRepoNameParams{
     		Provider:  in.GetContext().GetProvider(),
     		RepoOwner: nameParts[0],
     		RepoName:  nameParts[1],
    +		ProjectID: projectID,
     	})
     	if err != nil {
     		if errors.Is(err, sql.ErrNoRows) {
    
  • internal/controlplane/handlers_repositories.go+12 4 modified
    @@ -274,8 +274,12 @@ func (s *Server) GetRepositoryByName(ctx context.Context,
     		return nil, providerError(err)
     	}
     
    -	repo, err := s.store.GetRepositoryByRepoName(ctx,
    -		db.GetRepositoryByRepoNameParams{Provider: provider.Name, RepoOwner: fragments[0], RepoName: fragments[1]})
    +	repo, err := s.store.GetRepositoryByRepoName(ctx, db.GetRepositoryByRepoNameParams{
    +		Provider:  provider.Name,
    +		RepoOwner: fragments[0],
    +		RepoName:  fragments[1],
    +		ProjectID: projectID,
    +	})
     
     	if errors.Is(err, sql.ErrNoRows) {
     		return nil, status.Errorf(codes.NotFound, "repository not found")
    @@ -352,8 +356,12 @@ func (s *Server) DeleteRepositoryByName(ctx context.Context,
     		return nil, providerError(err)
     	}
     
    -	repo, err := s.store.GetRepositoryByRepoName(ctx,
    -		db.GetRepositoryByRepoNameParams{Provider: provider.Name, RepoOwner: fragments[0], RepoName: fragments[1]})
    +	repo, err := s.store.GetRepositoryByRepoName(ctx, db.GetRepositoryByRepoNameParams{
    +		Provider:  provider.Name,
    +		RepoOwner: fragments[0],
    +		RepoName:  fragments[1],
    +		ProjectID: projectID,
    +	})
     
     	if errors.Is(err, sql.ErrNoRows) {
     		return nil, status.Errorf(codes.NotFound, "repository not found")
    
  • internal/db/repositories.sql.go+11 5 modified
    @@ -188,17 +188,23 @@ func (q *Queries) GetRepositoryByRepoID(ctx context.Context, repoID int64) (Repo
     }
     
     const getRepositoryByRepoName = `-- name: GetRepositoryByRepoName :one
    -SELECT id, provider, project_id, repo_owner, repo_name, repo_id, is_private, is_fork, webhook_id, webhook_url, deploy_url, clone_url, created_at, updated_at, default_branch FROM repositories WHERE provider = $1 AND repo_owner = $2 AND repo_name = $3
    +SELECT id, provider, project_id, repo_owner, repo_name, repo_id, is_private, is_fork, webhook_id, webhook_url, deploy_url, clone_url, created_at, updated_at, default_branch FROM repositories WHERE provider = $1 AND repo_owner = $2 AND repo_name = $3 AND project_id = $4
     `
     
     type GetRepositoryByRepoNameParams struct {
    -	Provider  string `json:"provider"`
    -	RepoOwner string `json:"repo_owner"`
    -	RepoName  string `json:"repo_name"`
    +	Provider  string    `json:"provider"`
    +	RepoOwner string    `json:"repo_owner"`
    +	RepoName  string    `json:"repo_name"`
    +	ProjectID uuid.UUID `json:"project_id"`
     }
     
     func (q *Queries) GetRepositoryByRepoName(ctx context.Context, arg GetRepositoryByRepoNameParams) (Repository, error) {
    -	row := q.db.QueryRowContext(ctx, getRepositoryByRepoName, arg.Provider, arg.RepoOwner, arg.RepoName)
    +	row := q.db.QueryRowContext(ctx, getRepositoryByRepoName,
    +		arg.Provider,
    +		arg.RepoOwner,
    +		arg.RepoName,
    +		arg.ProjectID,
    +	)
     	var i Repository
     	err := row.Scan(
     		&i.ID,
    
  • internal/db/repositories_test.go+5 1 modified
    @@ -129,7 +129,11 @@ func TestGetRepositoryByRepoName(t *testing.T) {
     	repo1 := createRandomRepository(t, project.ID, prov.Name)
     
     	repo2, err := testQueries.GetRepositoryByRepoName(context.Background(), GetRepositoryByRepoNameParams{
    -		Provider: repo1.Provider, RepoOwner: repo1.RepoOwner, RepoName: repo1.RepoName})
    +		Provider:  repo1.Provider,
    +		RepoOwner: repo1.RepoOwner,
    +		RepoName:  repo1.RepoName,
    +		ProjectID: project.ID,
    +	})
     	require.NoError(t, err)
     	require.NotEmpty(t, repo2)
     
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

6

News mentions

0

No linked articles in our index yet.