Permissions issue while loading relations

I posted this in the slack channel and was asked to post it here.

We are noticing some oddity while loading relations in the last day. It has to do with permissions. It looks like the ownership permissions override role permissions for everything was have tested except loading relations. In this case, the roles permissions override the owner permission.

Hi Luke,

Thank you for reporting this issue. Unfortunately things like this happen despite how hard we try to prevent it. The team is working on an urgent patch. We will either apply the patch or rollback the deployment depending on which one will be done faster. Either way it will go back to the working condition by tomorrow morning. I apologize for the inconveniences this might have caused you.

Regards,
Mark

Hello @Luke_Jasudavicius

could you please describe the steps to reproduce the issue in the following way:

  1. Create table
  2. Set permission


  3. n. Execute:
curl  https://api.backendless.com/<app-id>/<api-key>/data/<table-name>?loadRelations=...

Result:
describe result

Expected result:
what you expect to get

The steps will speed up the research

Hello @sergey.kuk,

We’ve been able to reproduce this bug in the following way: (app ID: 36E4262F-E672-1A40-FFCF-B3523EB51200 )

  1. Created two tables “TestSet” and “TestItem”, where TestSet has just one column TestSet.items (1:N of TestItem)
  2. Both tables have all role permissions set to deny. However, the ownership policies have all permissions granted.
  3. Multiple objects owned by the same user are created in TestItem
  4. One object owned by that same user is created in TestSet, with the items column populated with those TestItem objects.
  5. Executed the following javascript on the client app:
        let result = await Backendless.Data.of('TestItem').find();
        console.log(result);
        let query = Backendless.DataQueryBuilder.create().setRelated('items');
        result    = await Backendless.Data.of('TestSet').findFirst(query);
        console.log(result);

Result:

First api call prints the expected result; an array with the three owned items
image

Second api call prints the object, with no “items” field at all
image

Expected result:

Second api call should print the object with the items field containing an array of the owned objects. We have only been able to get this to work by granting the “Load Relations” permissions on the relevant user roles. User role permissions for Load Relations unexpectedly overrides the object ownership policy.

Hello @Nathan_Cousins

Before Backendless 6.4.6 we do not check permissions when loading realations during the find operation (find, find by id, find first, find last). Now we check it, but we check it without counting object acl and owner policy. The security system is still multi-layered. For any load relations during find operation the system goes through several layers where each can trim the scope of the operations. The layered order of the decision making is consists of the following points of validation:

  1. Table permissions for the User account
  2. Table permissions for the user-defined roles
  3. Table permissions for system-level roles
  4. Global user-defined roles
  5. Global system roles

DENY has a higher priority than GRANT on the same layer.

Also, we have created an internal ticket to account owner policy BKNDLSS-26121. It will be implemented probably in a month. So the layered order of the decision making will probably consists of the following points of validation:

  1. Table permissions for the User account
  2. Table permissions for the user-defined roles
  3. Owner Policy
  4. Table permissions for system-level roles
  5. Global user-defined roles
  6. Global system roles

Hey @sergey.kuk ,

Thanks for the info. Glad to see the owner policy will be implemented in the near future.

For now, I suppose it’s safe to assume by allowing relations permissions on user roles won’t pose a security risk as long as the normal object retrieve permissions are denied? That way, a user can retrieve only objects they own, thus can only load relations for those objects. Hopefully that makes sense or I’m not missing something important.

Hello @Nathan_Cousins

I suppose it’s safe

In my opinion yes it will be safe. User object acl with owner policy works for general find and will be loaded only those relations that are tied with the object.

1 Like

Hi,

Could you advise if that patch on adding owner policy to relations has been applied ?
I am encountering a similar issue : although owner policy is explicitely set to allow load relations, the relations do not load.

Thanks.

Hello @Nicolas_REMY

Sorry, but it is not applied. The fix is pretty complicated, because it may impact performance in general.

Hi @sergey.kuk ,

Sorry, simultaneously with your reply, I cross-posted in Security of owned objects - #3 by Nicolas_REMY.

  1. Thanks for the reply. Does your reply mean that the fix is in the works but taking time, or does that mean that we should not expect it ?

  2. Could you advise as to the best role / owner policy setup in order to restrict access to a minimum ?

→ Indeed, for example when the relation’s target is a user, then at present I need to allow a specific role to access all users instead of those specifically owned by the parent record’s owner.

→ Thus, I am worried that users with that role will be able to access all users instead of a few. Am I wrong ?

→ If so, the same goes for any other type of data. It’s just that user info is so particularly sensitive that it made for a good example.

  1. If I may, it would perhaps be useful to specify in the documentation Security - Backendless REST API Documentation that relations are an exception to point 4. I understood it followed the rule and spent hours trying to make out what was wrong.