rbac: dbauthz fails closed when fetching related resources
- 主要言語
- 言語のデータがありません
- スター
- 3
- フォーク
- 0
- PR マージ指標
- 30日以内にマージされた PR はありません
説明
**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
コントリビューションガイド
このリポジトリのコントリビューションガイドは索引されていません
調査の方向性
dbgen.ProvisionerJob の再現から始め、GetProvisionerJobByID のパスを追跡します。そこには、関連リソース B が取得される箇所と sql.ErrNoRows が外部に伝播する箇所も含めます。関連リソースが存在しない場合の既存の RBAC または dbauthz テストを確認します。欠落したリソースによって、データベースエラーが露出するのではなく、意図した fail-open の認可結果が生成されれば完了です。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- go, sql
- 領域
- authorization, backend
- issue の種類
- バグ
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 活発さ
- 停滞
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 45/100