Skip to content
This repository was archived by the owner on Dec 15, 2020. It is now read-only.

Modify User (as a regular user) fails #891#959

Merged
murphybytes merged 10 commits into
kolide:masterfrom
murphybytes:bug_891
Jan 17, 2017
Merged

Modify User (as a regular user) fails #891#959
murphybytes merged 10 commits into
kolide:masterfrom
murphybytes:bug_891

Conversation

@murphybytes
Copy link
Copy Markdown
Contributor

No description provided.

@groob
Copy link
Copy Markdown
Contributor

groob commented Jan 14, 2017

Shouldn't validateModifyUser be deleted now? With the changes that @zwass added to change password and the removal of this function call in this PR, it looks like dead code to me. Let's remove it.

Other than that, the change LGTM.

@groob
Copy link
Copy Markdown
Contributor

groob commented Jan 14, 2017

using the canPerformactions Middleware allows the user to modify any of the properties in the ModifyUser method. https://github.com/kolide/kolide-ose/blob/3802f3098ecd3c0a5fab7b955e4ff71803dbfddc/server/service/service_users.go#L52

This would include some very undesirable security issues such as allowing a user to disable their own account and promote themselves to Admin.

Either update the validateModifyUser endpoint and use that, or introduce separate endpoints for security sensitive modifications on a user. I think @zwass had plans to do the latter.

Copy link
Copy Markdown
Contributor

@groob groob left a comment

Choose a reason for hiding this comment

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

implement changes in the comments above

@murphybytes
Copy link
Copy Markdown
Contributor Author

After discussing with @groob I added two new endpoints that allow admin users to set/unset admin and enabled status for users. Not the id in the url is the id of the user whose admin or enabled status will be changed. This simplifies the authorization of these operations.

{ "enabled": trueorfalse}
/api/v1/kolide/users/{id}/enable
{"admin": trueorfalse}
/api/v1/kolide/users/{id}/admin

If operations succeed an empty response is returned. If a user isn't an admin the http status is 503, otherwise a standard error structure is returned describing what went horribly awry.

@groob
Copy link
Copy Markdown
Contributor

groob commented Jan 16, 2017

The new endpoints should not use PATCH, use POST instead.

@groob
Copy link
Copy Markdown
Contributor

groob commented Jan 16, 2017

If you're returning an empty response, make sure the code is 204 NO Content.

IMO it would be more consistent to return the modified user in the response.

Comment thread server/mock/datastore_users.go Outdated
SaveUserEnabledFuncInvoked bool
}

func (s *UserStore) SaveUserAdmin(id uint, isAdmin bool) error {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Was this generated?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

no

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This file is for generated code. There's a helpers file for handwritten methods.

@murphybytes
Copy link
Copy Markdown
Contributor Author

@groob I'd favor returning the request with the new values instead of the whole user object. The reason being is that fetching the user would entail another sql select request and a network round trip for nothing. Admittedly, it's not a huge cost, but essentially it's burning cycles for nothing.

Comment thread server/kolide/users.go Outdated
SaveUser(user *User) error
// SaveUserAdmin sets the value of the user admin field for user identified
// by id.
SaveUserAdmin(id uint, isAdmin bool) error
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

These methods should not exist. Just use SaveUser

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

👍

Comment thread server/mock/datastore_users.go Outdated

type SaveUserFunc func(user *kolide.User) error

type SaveUserAdminFunc func(id uint, isAdmin bool) error
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Need to remove these methods. they're not in the PR anymore.

Comment thread server/service/endpoint_users.go Outdated
payload := kolide.UserPayload{
Admin: &req.Admin,
}
user, err := svc.ModifyUser(ctx, req.ID, payload)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

These endpoints can't use the ModifyUser method on service as they're shared by the ModifyUser endpoint, which has different authorization.

The service methods must exist and be different. Only the datastore method for SaveUser can be shared. Sorry for the confusion.

Comment thread server/service/endpoint_users.go Outdated
Admin: &req.Admin,
}
user, err := svc.ModifyUser(ctx, req.ID, payload)
user, err := svc.User(ctx, req.ID)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The endpoint factory function is for creating an endpoint, not for business logic. Any app changes should happen within the service layer. This might sound odd but the separation of concerns allows us to cleanly add metrics, logging, validation and so on.

I'd revert this commit and create two service methods for the actions you're adding.

Copy link
Copy Markdown
Contributor

@groob groob left a comment

Choose a reason for hiding this comment

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

a few more small nits.

Comment thread server/kolide/users.go

// ModifyUser updates a user's parameters given a UserPayload.
ModifyUser(ctx context.Context, userID uint, p UserPayload) (user *User, err error)
// ChangeUserAdmin is used to modify the admin state of the user identified by id.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Add spacing like the rest of the documented methods on this service.

Comment thread server/kolide/users.go Outdated
// ModifyUser updates a user's parameters given a UserPayload.
ModifyUser(ctx context.Context, userID uint, p UserPayload) (user *User, err error)
// ChangeUserAdmin is used to modify the admin state of the user identified by id.
ChangeUserAdmin(id uint, isAdmin bool) (*User, error)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

add the ctx context.Context method as a first param to all service methods. We populate context with information like who is making the request.

Finally, add the user and err params for the return types. I am only asking for this last one because when working with the types package to do codegen/refactoring, it helps to have the variable names.

Comment thread server/kolide/users.go Outdated
// ChangeUserAdmin is used to modify the admin state of the user identified by id.
ChangeUserAdmin(id uint, isAdmin bool) (*User, error)
// ChangeUserEnabled is used to enable/disable the user identified by id.
ChangeUserEnabled(id uint, isEnabled bool) (*User, error)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

in addition to implementing these methods on service , implement them with the loggingMiddleware and metricsMiddleware types in the service package.

Copy link
Copy Markdown
Contributor

@groob groob left a comment

Choose a reason for hiding this comment

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

Address the review comment regarding 1 line spacing above documented methods. the rest looks good.

@murphybytes murphybytes merged commit 56b8772 into kolide:master Jan 17, 2017
@murphybytes murphybytes deleted the bug_891 branch January 17, 2017 16:44
@groob groob mentioned this pull request Jan 17, 2017
3 tasks
zwass added a commit that referenced this pull request Sep 18, 2018
The ability to modify a users admin and enabled status was erroneously left in
place during development of #959. To
mitigate a privilege escalation vulnerability we need to ensure those values
can only be modified through the explicit methods.

This patch includes a unit test and fix for the vulnerability.

Thanks to 'Quikke' for submitting this vulnerability.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants