Skip to content

feat: Return more 404s vs 403s #2194

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Jun 14, 2022
Merged

feat: Return more 404s vs 403s #2194

merged 16 commits into from
Jun 14, 2022

Conversation

Emyrk
Copy link
Member

@Emyrk Emyrk commented Jun 8, 2022

Issue: #1899

403 -> 404 changes

  • File not exist
  • Parameter not exist
  • Provisioner Job not exist
  • Organization not exist
  • Workspace not exist
  • User not exist

@Emyrk Emyrk marked this pull request as ready for review June 9, 2022 00:46
@Emyrk Emyrk requested a review from spikecurtis June 9, 2022 13:43
Copy link
Contributor

@spikecurtis spikecurtis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, just generally speaking, this PR returns 404 correctly, but is not comprehensive in the sense that there are still cases where we return 403s when we shouldn't---and that's a security leak.

I'm uncomfortable, but conflicted, about whether to support a PR that makes correct changes, but leaves us in a state where we leak info. Would it be worth pairing on chasing down the other places that we should return 404?

coderd/files.go Outdated
@@ -86,7 +86,9 @@ func (api *API) fileByHash(rw http.ResponseWriter, r *http.Request) {
}
file, err := api.Database.GetFileByHash(r.Context(), hash)
if errors.Is(err, sql.ErrNoRows) {
httpapi.Forbidden(rw)
httpapi.Write(rw, http.StatusNotFound, httpapi.Response{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this reintroduces the security concern that now you can distinguish between whether it exists or not even if you have no access. We should also return 404 on line 102 of this file.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see what you mean. Before we were returning 403 to be consistent, but that is not a good UX.

If authorize returns a 404 in some cases, can that be a bad UX?


My question is mainly, are these security concerns ones we should take as important right now. If we return a 403 vs 404 we do leak the info so the user knows if the resource exists or not. Is that a security issue we should take seriously right now? (Honest question)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security impact is minor in a real sense, but paints us in a "these people don't know what they're doing" light to security minded people, so IMO the impact is basically on par with the confusion we had before.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So it look like I need to make Authorize return a 404 message consistent with the existing 404 message

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. It would be good to have one 404 code path that we use everywhere so we can standardize messaging.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@spikecurtis Will fix this now.

@spikecurtis
Copy link
Contributor

A high level problem is that api.Authorize returns 403, but it seems like in maybe 50% or more of cases, we should be returning 404 to prevent information leaks.

The high level change we should make is ensuring that all 404s look the same: same message etc. Easy to leak information by sending one message if the object exists and a different one if it really doesn't.

@Emyrk Emyrk marked this pull request as draft June 10, 2022 14:42
@Emyrk Emyrk marked this pull request as ready for review June 10, 2022 19:02
@Emyrk Emyrk requested a review from spikecurtis June 10, 2022 21:22
@@ -411,7 +418,8 @@ func (api *API) putUserPassword(rw http.ResponseWriter, r *http.Request) {

// admins can change passwords without sending old_password
if params.OldPassword == "" {
if !api.Authorize(rw, r, rbac.ActionUpdate, rbac.ResourceUser.WithID(user.ID.String())) {
if !api.Authorize(r, rbac.ActionUpdate, rbac.ResourceUser.WithID(user.ID.String())) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as an aside, it is very unintuitive to me that this check should fail for my own user.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not? There is ResourceUser and ResourceUserData. The former cannot be edited by "me"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess that's just it. Why can't I edit my own "ResourceUser" resource? The code says

	// ResourceUser is the user in the 'users' table.
	// ResourceUser never has any owners or in an org, as it's site wide.
	// 	create/delete = make or delete a new user.
	// 	read = view all 'user' table data
	// 	update = update all 'user' table data
	ResourceUser = Object{
		Type: "user",
	}

Things like email and password are in the users table, and users can change them, no?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, I need to fix that comment. The comment is incorrect as I since placed email as a ResourceUserData. There was some thrashing there and now the comment is stale.

My mistake

@Emyrk Emyrk requested a review from spikecurtis June 13, 2022 21:30
@Emyrk Emyrk merged commit 2513167 into main Jun 14, 2022
@Emyrk Emyrk deleted the stevenmasley/404_vs_403 branch June 14, 2022 15:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants