coder / coder/internal

rbac: dbauthz fails closed when fetching related resources

Ouverte
#262 3 commentaires 0 réactions 0 personnes assignées Voir sur GitHub
help wanted tech-debt
Langage dominant
Aucune donnée de langage
Étoiles
3
Forks
0
Métriques de merge des PR
Aucune PR mergée en 30 j

Description

**Problem:**

Given:
- You have resource A related to resource B
- You authorize actions on resource A by checking relevant permissions on resource B
- Resource A exists, but for some reason references to a nonexistant resource B

When:
- You ask if you can do X on A

Then:
- You get `sql.ErrNoRows` relating to the fetch of resource B, which is _completely unintuitive_

This was encountered when writing a test case for provisioner jobs using `dbgen.ProvisionerJob`, but I could imagine a situation where this could arise in the "real world".

Example to reproduce:

```
var defOrgID uuid.UUID
if orig.OrganizationID == uuid.Nil {
defOrg, _ := db.GetDefaultOrganization(genCtx)
defOrgID = defOrg.ID
}

jobID := takeFirst(orig.ID, uuid.New())
// Always set some tags to prevent Acquire from grabbing jobs it should not.
tags := takeFirstMap(orig.Tags, database.StringMap{"user": "", "scope": "organization"})
if orig.Tags == nil && !orig.StartedAt.Time.IsZero() {
// Make sure when we acquire the job, we only get this one.
tags[jobID.String()] = "true"
}

job, err := db.InsertProvisionerJob(genCtx, database.InsertProvisionerJobParams{
ID: jobID,
CreatedAt: takeFirst(orig.CreatedAt, dbtime.Now()),
UpdatedAt: takeFirst(orig.UpdatedAt, dbtime.Now()),
OrganizationID: takeFirst(orig.OrganizationID, defOrgID, uuid.New()),
InitiatorID: takeFirst(orig.InitiatorID, uuid.New()),
Provisioner: takeFirst(orig.Provisioner, database.ProvisionerTypeEcho),
StorageMethod: takeFirst(orig.StorageMethod, database.ProvisionerStorageMethodFile),
FileID: takeFirst(orig.FileID, uuid.New()),
Type: takeFirst(orig.Type, database.ProvisionerJobTypeWorkspaceBuild),
Input: takeFirstSlice(orig.Input, []byte("{}")),
Tags: tags,
TraceMetadata: pqtype.NullRawMessage{},
})
_ = job
require.NoError(t, err, "insert job")
job, err = db.GetProvisionerJobByID(genCtx, jobID)
require.NoError(t, err, "get job: %s", jobID.String())

```

**Suggested solution:**

Fail open if the related resource is not present instead.

cc @mafredri

Guide de contribution

Aucun guide de contribution indexé pour ce dépôt

Piste de recherche

Commencez par reproduire dbgen.ProvisionerJob et suivez le chemin de GetProvisionerJobByID, notamment l’endroit où la ressource associée B est récupérée et où sql.ErrNoRows s’échappe. Examinez les tests RBAC ou dbauthz existants pour les ressources associées manquantes ; c’est terminé lorsque la ressource manquante produit le résultat d’autorisation fail-open attendu au lieu d’exposer l’erreur de la base de données.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
go, sql
Domaine
authorization, backend
Type d'issue
Bug
Difficulté
4/5
Temps estimé
3-5 jours
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
45/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.