Skip to content
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

Prevent syncing row changes between users for views filtered by current user #15163

Merged
merged 5 commits into from
Dec 13, 2024

Conversation

aptkingston
Copy link
Member

@aptkingston aptkingston commented Dec 11, 2024

Description

This PR prevents syncing row changes between users when using views that are filtered by any current user property. This is required as it can otherwise expose data which should not be seen by other users. I'm just stringifying and searching the query property for the presence of a current user binding as my litmus test.

Currently the view doc is fetched and checked whenever a user connects to a certain datasource, which is infrequent - typically just once per page load, so I don't think there's much to be gained my computing this on update and storing a flag into the doc, but opinions are welcome.

Also contains a tiny fix for scrollbar styles as they have looked wrong for a few months and it's about time they were fixed!

Addresses

Copy link

qa-wolf bot commented Dec 11, 2024

QA Wolf here! As you write new code it's important that your test coverage is keeping up.
Click here to request test coverage for this PR!

@aptkingston aptkingston changed the title Prevent syncing changes between users for views filtered by current user Prevent syncing row changes between users for views filtered by current user Dec 11, 2024
@aptkingston aptkingston marked this pull request as ready for review December 12, 2024 08:33
@aptkingston aptkingston requested a review from a team as a code owner December 12, 2024 08:33
@aptkingston aptkingston requested review from mike12345567 and removed request for a team December 12, 2024 08:33
return sanitizedBinding
}
})
.some(binding => binding?.includes("[user]"))
Copy link
Collaborator

Choose a reason for hiding this comment

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

Will this always be the only true case? Could we not get other issues such as formulas or similar?

Copy link
Member Author

Choose a reason for hiding this comment

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

For this fix we only care about data segregated per user. There's a wider problem of data not matching filters in general, but by identifying user bindings we can fix cases where users are seeing row they should not be able to access. Only the current user bindings create this security risk. This PR is deliberately only targetting user bindings and is not meant to be a wider fix.

valid = false
}
}
if (!valid) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

More of a product discussion, but are we exposing this somehow to the user? Otherwise they might think it's actually broken

Copy link
Member Author

Choose a reason for hiding this comment

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

We aren't, no. But I think that's ok, as you wouldn't expect to be able to see rows created by other users if using a view that's filtered to show only your own rows.

Copy link
Collaborator

@adrinr adrinr left a comment

Choose a reason for hiding this comment

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

It looks like the issue is not related to the user filter, but on any filter. Create a different view that, for example, filters by "title starting with a". The same issue will happen, as the grid socket will push the row ignoring any filter.

Screen.Recording.2024-12-12.at.10.40.37.mov

@aptkingston
Copy link
Member Author

It looks like the issue is not related to the user filter, but on any filter. Create a different view that, for example, filters by "title starting with a". The same issue will happen, as the grid socket will push the row ignoring any filter.

Screen.Recording.2024-12-12.at.10.40.37.mov

The same thing does happen with all filters yes, but it's less significant for other filters. We are prioritising a quick solution specifically for user-segregated data as that has larger security implications compared to just seeing rows which don't match the currently applied filters.

I agree we need a wider solution for all filters, but it's not an easy fix. It will probably require evaluating all filters server side against rows before broadcasting them down the websocket.

@adrinr
Copy link
Collaborator

adrinr commented Dec 12, 2024

It looks like the issue is not related to the user filter, but on any filter. Create a different view that, for example, filters by "title starting with a". The same issue will happen, as the grid socket will push the row ignoring any filter.
Screen.Recording.2024-12-12.at.10.40.37.mov

The same thing does happen with all filters yes, but it's less significant for other filters. We are prioritising a quick solution specifically for user-segregated data as that has larger security implications compared to just seeing rows which don't match the currently applied filters.

I agree we need a wider solution for all filters, but it's not an easy fix. It will probably require evaluating all filters server side against rows before broadcasting them down the websocket.

We already have a way to analyse the filters on the backend. We use it to filter them in memory, so we could check it they are part of the filter or not. If there is rush of shipping this one, we can go for it. Or if you want me to have a look at the filter part, I am happy to do it. I really think we can reuse everything we already have (if we have the context that this websocket is for a view)

@aptkingston
Copy link
Member Author

I think we'll need to release this in the meantime, because the other solution is a much larger change. Right now you just subscribe to a datasource and that's the identifier for changes. We would have to refactor things so that users resubscribe when their query changes (their local frontend query which can be attached to any DS+).

I think the flow would look something like:

  • Clients resubscribe every time they are searching using a new query, in the case of using a table or appending additional filters to a view
  • Serverside we store every connection's query
  • Serverside we fetch and cache the current user doc for every connection
  • Whenever a document change is detected, for each connection we use the current user doc, view built-in query (if a view), and any additional frontend filters to create a single enriched query. If this is a view with a built in query and the user also has an additional frontend query, these must be joined together, then the whole thing is enriched with the current user
  • Evaluate that query against the doc
  • Broadcast the change to users which the query matches against

It's pretty significant and there is some time pressure to release this one, so I think we should proceed with this for now.

Copy link
Collaborator

@adrinr adrinr left a comment

Choose a reason for hiding this comment

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

Good to go with this solution temporally

@aptkingston aptkingston merged commit 640008d into master Dec 13, 2024
20 checks passed
@aptkingston aptkingston deleted the cheeks-fixes branch December 13, 2024 11:47
@github-actions github-actions bot locked and limited conversation to collaborators Dec 13, 2024
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.

2 participants