raystack / raystack/frontier

UpdateProjectResource: title wipe, 403-vs-404 on missing resource, 500 on bad project_id, unguarded cross-org move

Open
#1,697 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

authz bug
Dominant language
Go
Stars
344
Forks
47
Avg merge
4d 4h
Merged PRs (30d)
26

Description

Summary

While verifying PR #1686 (UpdateProjectResource now reconciles #project/#owner relations) end-to-end against a local server, a few pre-existing issues surfaced in UpdateProjectResource and the resource authorization path. The PR's own behavior is correct — these are separate, and most predate it. Filing together.


1. UpdateProjectResource silently wipes the resource title

The handler builds the resource.Resource it passes to the service without reading body.title, so Title is always empty. Combined with the repository now persisting title, any update blanks the title — even if the request body sets one.

Repro

  1. CreateProjectResource with title: "Original Title".
  2. UpdateProjectResource for it (with or without title in the body).
  3. Read the resource.

Actual: stored title becomes "".
Expected: title is preserved, or updated to the value sent in the body.

Note: this lives in the same RPC PR #1686 reworks, so it may be worth addressing there.


2. Updating a nonexistent resource returns 403 PermissionDenied instead of 404 NotFound

The authorization interceptor runs CheckAuthz(caller, <resource>, "update") before the service checks existence. For a resource id that doesn't exist there are no #project/#owner/org relations to resolve authority through, so even a platform superuser is denied — and the handler's ErrNotExist → NotFound mapping is effectively unreachable.

Repro: UpdateProjectResource with a random (valid-UUID) id in an existing namespace.
Actual: 403 permission_denied. Expected: 404 NotFound (or a deliberate not-leak-existence decision, documented).


3. UpdateProjectResource with a bad project_id returns 500 Internal

The handler resolves the parent project up front and wraps any GetProject error as CodeInternal, so a non-existent/invalid project_id surfaces as a 500.

Repro: UpdateProjectResource with project_id set to a random UUID.
Actual: 500 internal. Expected: 400 InvalidArgument or 404 NotFound.


4. Resources can be moved across organizations with no guard

UpdateProjectResource lets you move a resource to a project that belongs to a different organization; the #project relation is repointed to the other org's project and the move succeeds. PR #1686 makes project moves actually take effect, so this is now reachable.

Repro: create a resource under a project in org A, then UpdateProjectResource with project_id of a project in org B.
Actual: 200, resource now lives under org B's project.
Question: is a cross-org move intended? If not, it should be rejected; the resource otherwise ends up under a different org's hierarchy.


5. Resource-mutation RPCs require the namespace to define the matching verb (related to #1693)

UpdateProjectResource/DeleteProjectResource/GetProjectResource run an authz precheck for update/delete/get on the resource type. A custom namespace created via CreatePermission only has the verbs you defined, so if it lacks (say) update, the precheck fails at schema-compile time:

IsAuthorized.CheckAuthz ... FailedPrecondition: relation/permission `update` not found under definition `<namespace>`

and the call 500s. This is the same family as the DeleteProjectResource 500 in #1693 (finding 1); noting here for completeness as it affects update/get too.


Found while manually testing PR #1686. The reconcile behavior in that PR works correctly.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing the UpdateProjectResource handler, its GetProject lookup, and the authorization precheck; reproduce the listed update requests for titles, missing resources, invalid projects, cross-organization moves, and custom namespaces. Done means each case has an intentional, documented result and the resource title and organization hierarchy remain correct.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
authorization, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.