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

ZOOKEEPER-2590:exists() should check read ACL permission #1298

Closed
wants to merge 1 commit into from

Conversation

maoling
Copy link
Member

@maoling maoling commented Mar 28, 2020

  • exist is a kind of read operation, so it should check read ACL permission. In the original release, only two operation don't check ACL permission(exist and getAcl) which is an omission. I saw getAcl had also amended it
  • more details in the ZOOKEEPER-2590

Copy link
Contributor

@eolivelli eolivelli left a comment

Choose a reason for hiding this comment

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

Overall okay

What about adding a configuration parameter?
The check will be enabled by default.
Maybe this additional check may break (broken) applications.
We should leave a way to let the system work in production while fixing the broken application

@maoling
Copy link
Member Author

maoling commented Mar 30, 2020

@eolivelli
BTW, where is Jenkins these days? without Jenkins unit cases build, sometimes cannot make sure whether one patch has changed the behavior

@anmolnar
Copy link
Contributor

anmolnar commented Nov 15, 2023

@maoling @eolivelli Would you mind resurrecting this patch?

Patch looks good to me, but it's not enough alone to fix the original issue. Currently exists() doesn't check ACL, so nodes can be easily 'scanned' for existing even if the user doesn't have permission to the znode or the parent znode.

For instance:

/a - protected
/a/b - protected
/a/c - not protected

In this case an unauthorized user should not be able to see anything under /a, because we check ACL in getChildren(). With the current impl of exists(), he can scan through nodes /a/a, /a/b, /a/c, etc. to see which one exists. This still can be done with this patch, because he will get:

stat /a - Insuff perm
stat /a/b - Insuff perm
stat /a/c - exists
stat /a/d - Node does not exist

I suggest the following:

  • Check nearest parent znode ACL in exists(), which is /a in my example and it's /b for stat /a/b/d/e/f/g/h. In this case the user will get Insuff perm for all the above requests.
  • Put this behind a feature flag and let the default behaviour of exists() unprotected (current situation).

cc @phunt

@phunt
Copy link
Contributor

phunt commented Nov 15, 2023

That's good insight Andor. I think we should also document this, and perhaps consider changing the default behaviour of the feature flag at some point? Eg we could add as you suggest in 3.10, and change the default to "protected by default" in 3.11? That would give people sufficient warning to upgrade their client code.

ztzg added a commit to ztzg/zookeeper that referenced this pull request Nov 16, 2023
(Ported from f11f8e5 / apache#1298
to 'master' by Damien Diederen; no other changes.)

Co-Authored-By: Damien Diederen <ddiederen@apache.org>
@ztzg
Copy link
Contributor

ztzg commented Nov 16, 2023

Hi @maoling, @eolivelli, @anmolnar,

I have forward-ported @maoling's patch here:

https://github.com/ztzg/zookeeper/tree/ZOOKEEPER-2590-exists-acl-check

Here is the specific commit:

ztzg@830aecd

(I have not opened another PR; this one is perfectly fine. @maoling, don't hesitate to update it with the contents of my tree.)

@anmolnar
Copy link
Contributor

I changed my mind, implementing the parent ACL check doesn't make much sense. The same 'scan' issue can be achieved with get too:

/a - protected
/a/b - protected
/a/c - not protected
/a/d - not exist

Scanning with get:

[zk: localhost:2181(CONNECTED) 9] ls /a
Authentication is not valid : /a
[zk: localhost:2181(CONNECTED) 10] get /a/b
org.apache.zookeeper.KeeperException$NoAuthException: KeeperErrorCode =
NoAuth for /a/b
[zk: localhost:2181(CONNECTED) 11] get /a/c
null
[zk: localhost:2181(CONNECTED) 12] get /a/d
org.apache.zookeeper.KeeperException$NoNodeException: KeeperErrorCode =
NoNode for /a/d

There's no point fixing exists() recursively. ZooKeeper ACLs are not recursive means that such protection against scanning attacks cannot be provided.

I tend to accept @maoling 's patch as it is, because doing anything more will increase complexity without adding value.

@eolivelli
Copy link
Contributor

Makes sense.
We just have to document the behavior

@anmolnar
Copy link
Contributor

@eolivelli @ztzg @phunt

Unfortunately @maoling is not active on this patch, I suggest to fork his patch and create a new PR to move forward with the fix.

@eolivelli
Copy link
Contributor

I agree. But I don't have cycles

@anmolnar
Copy link
Contributor

I agree. But I don't have cycles

No worries, I'll do it.

@anmolnar
Copy link
Contributor

Closing this PR in favor of #2093

@anmolnar anmolnar closed this Nov 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants