-
Notifications
You must be signed in to change notification settings - Fork 259
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
[Feature] Shared cache grants check option #466
base: master
Are you sure you want to change the base?
Conversation
d3f39b7
to
040e69d
Compare
040e69d
to
60b7596
Compare
fyi I'm a bit busy to review your PR, I asked the other maintainer to see if someone can have a look |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello @hulk8 and thanks for your contribution. I had a look at the code, it is pretty straightforward.
What I'd love to see is some tests around the feature you are adding and also if you could fix lint issues.
@@ -146,6 +146,25 @@ func (rp *reverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) { | |||
} | |||
|
|||
if shouldReturnFromCache { | |||
// if cache shared between all users | |||
// try to check if cached query is allowed for current user | |||
if s.user.cache != nil && s.user.cache.SharedWithAllUsers && s.user.cache.CheckGrantsForSharedCache { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure to properly understand why we need to check s.user.cache
here ? what is the goal of this.
Isn't Checking if a cache is shared && that we should check grants enough ?
rp.proxyRequest(s, srwCheck, srw, checkReq) | ||
|
||
if srwCheck.statusCode == http.StatusOK { | ||
log.Debugf("%s: check grants for shared cached query request success; query: %q; Method: %s; URL: %q", s, checkQuery, checkReq.Method, checkReq.URL.String()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe adding the user would be nice in the debug logs, wdyt ?
Description
Summary
I want to add some feature option for fixing possible insecure shared cache behavior with
shared_with_all_users
option enabled.User who haven't grants for tables in query can get cached result if another user who have sufficient grants already executed same query (like
SELECT * FROM table
) because only user authorization checked before cache read but not grants (withoutshared_with_all_users
enabled request will be redirected to click and then failed if user have insufficient grants).Example
For example, if we have ClickHouse database
ny_taxi
(from dataset examples) withuser_A
anduser_B
:and
chproxy
config:I want to review 3 cases:
user_C
trying to execute query throughchproxy
. He will have403 Forbidden
status code with response content:And this is OK.
2. If
user_B
who is present in ClickHouse will try to execute querySELECT * FROM ny_taxi.trips LIMIT 10
for example. He will receive500 Internal Server Error
with response content:And this is OK too.
3. If
user_A
who is present in ClickHouse and have grants forny_taxi.trips
will execute querySELECT * FROM ny_taxi.trips LIMIT 10
he will receive200 Ok
and response data, which will be also cached infile_system_cache
. And finally, until cached result expiresuser_B
(who haven't sufficient grants forny_taxi.trips
) and any other user can execute this exact query and get cached response data even if they have no grants forSELECT
onny_taxi.trips
. It works because ofshared_with_all_users
.And this is not so good, but, as far as I understand, was designed this way.
Solution
My proposition is:
check_grants_for_shared_cache
incaches
section which enables or disables additional grants check for cached request.shared_with_all_users: true
andcheck_grants_for_shared_cache: true
. This check will be performed only when user executes query and before load shared cache result. This check will create new request to ClickHouse (with same request scope) with wrapped original query intoDESC ({{original_query}})
. Along with query parsed and analyzed for return types (which is fast) ClickHouse checks permissions for the user to execute the query.This solution I implemented in the PR.
Pull request type
Please check the type of change your PR introduces:
Checklist
Does this introduce a breaking change?
Further comments
In my cases of usage
chproxy
, shared cache between users is very helpful with some BI instruments, because:Security issue like this, when user can access to data (cached) with insufficient grants prevent from using shared cache in this cases.
This is the first draft and I will refactor it later if this is useful feature.
I will be glad, if someone can give me a hint to implement 3 cases from Example in tests.