Logical security over Current User actions

Yoo! How are you !?

I have been doing some work around logical security based on current user information, like ´if this topic.creator.username to be equals to User.current().username´ I allow the user to edit topic or exclude!

So, the point is, I need to guarantee some actions based on User session! But I have been doing some tests, and that’s why I’m here now asking you.

Through Javascript in web browser (even in production mode), I’m capable of Discourse.User.current().set(‘username’, ‘sometestename’). This way, some actions in my system would be enabled just by this change. I know It’s not the goal of 99% of the users, but above this case, do you know guys some way to make sure user will not manipulate user information ?

Best Regards,
Felipe

1 Like

If you change information in your local browser, that does not change anything on the back end.

The User is logged in via an authentication token, I believe, so you can’t masquerade as anyone else to the back-end:

Because there is no fooling the server, you will not be able to make any change as another user.

As soon as you refresh the browser, your local changes will probably be wiped out. Worst case you will probably mess up the javascript app state and have to delete your cache.

4 Likes

Yoo! Yeah!

As you said, the best way so would be always get current user session from back-end server.

This way, cache changes from the browser couldn’t affect! Do you know somewhere I can check that logical security is based on user session from backend server, and not from PreloadStore ?

Warn me if i’m pointing out wrong way! Thank you Robert for help!

Best Regards,
Felipe

I’m no security expert, just an app dev, but all persistent changes can only be made on the server. What happens on the browser in EmberJS is for the user’s convenience and superior usability experience, eg. caching for speed, automagic app-like interface behaviour. It doesn’t change the fact that ultimately it has to negotiate all persistent changes with the Rails server, and in doing so will only have permission to do so for the logged in user.

Same goes for all data retrieval - the rails server is only going to send out data the logged in user is privy to.

I don’t think you need to worry about this, because if anyone were to try to subvert this, they would fall at the first hurdle: there is no way to fool the API.

What is your concern?

1 Like

I’m concerned because I’m working in some approaches which such action will be available or not depending on your User, if you are topic creator, if you are post creator, so this way I need to validate based on backend user session.

Like this, on post the user can edit it, if you are the post creator.

EDIT: Like the discourse post permissions, i will check it.

Screen Shot 2020-11-23 at 19.47.42

Best Regards, Felipe

You should develop all the security measures firstly on the back end.

The rails serializers determine what data gets sent.

The Guardian protects what actions are allowed.

All of this is managed by the Rails Controllers.

It doesn’t matter what junk the front end sends or what it requests to retrieve, because those elements protect the server.

You can mirror this with front end behaviour, but the front end is not the gatekeeper.

Check out a few of the larger plugins and you will see examples of Serializers and use of the Guardian.

4 Likes

Thank you Robert, I needed this feedback!

I will check it for sure!

Best Regards,

1 Like

Yoo Robert!

I have been analyzing plugin code and codebase about post controls (actions). To check which I could do the most about security.

As analyzed! By front-end there are some steps which make sure if user can edit or not the post, like:

  • 1° step: SiteSetting.post_menu_hidden_items
  • 2° step: attrs.canEdit
  • 3° step: editPost() - !post.can_edit - controllers/topic

But, even if manipulated by front, one time sent to the back end server in posts_controller.rb, in

def update

It req again the post, by Rails, as a ultimate checks:

  • !guardian.public_send(“can_edit?”, post)
  • guardian.ensure_can_edit!(post)
  • PostRevisor

Thank you for your insights!
That’s so great.

1 Like

Well done. Very pleased you kept going and dug further :+1:t2: