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

dbms.security.procedures.roles not working with custom procedures and dbms.cluster.routing.getRoutingTable in ONgDB 3.6.0 with apoc 3.5.0.12 #77

Open
wtrevena opened this issue Jul 23, 2020 · 5 comments

Comments

@wtrevena
Copy link

wtrevena commented Jul 23, 2020

Expected Behavior

dbms.security.procedures.default_allowed & dbms.security.procedures.roles provide procedure level user access control for custom procedures defined via "CALL apoc.custom.asProcedure()" and for the dbms.cluster.routing.getRoutingTable procedure necessary for neo4j:// bolt+routing calls.

Actual Behavior

dbms.security.procedures.default_allowed & dbms.security.procedures.roles provide procedure level user access control for some procedures, but not for custom procedures or for the dbms.cluster.routing.* family.

How to Reproduce the Problem

wget https://cdn.graphfoundation.org/ongdb/dist/ongdb-enterprise-3.6.0-unix.tar.gz
tar -xzf ongdb-enterprise-3.6.0-unix.tar.g
wget https://cdn.graphfoundation.org/apoc/dist/org/neo4j/procedure/apoc/3.5.0.12/apoc-3.5.0.12-all.jar
mv apoc-3.5.0.12-all.jar plugins/apoc-3.5.0.12-all.jar
  1. Create a new role and assign a user to that role
"CALL dbms.security.createRole('lowlife')"
"CALL dbms.security.createUser('user','password')"
"CALL dbms.security.addRoleToUser('lowlife','user')"
  1. Define a custom procedure such as
"CALL apoc.custom.asProcedure('listcity','MATCH (n:city {stateabr:$stateabr}) RETURN n LIMIT 10','read',[['n','NODE']],[['stateabr','STRING']]);"
  1. Add the following lines to neo4j.conf
dbms.directories.plugins=/db/plugins
dbms.security.procedures.default_allowed=admin
dbms.security.procedures.roles=custom.*:lowlife;dbms.cluster.routing.getRoutingTable:lowlife
dbms.security.procedures.unrestricted=*
dbms.security.procedures.whitelist=*
  1. Start Neo4j
    /bin/neo4j start

  2. Call the custom procedure

"CALL custom.listcity('WA');"

Example of how dbms.security.procedures.roles works for some procedures but not others

"CALL custom.listcity('WA');" leads to this error message if you use neo4j:// and the configuration above

image

Or to this error message if you use bolt://

image

Furthermore, when I ran

"CALL dbms.procedures() YIELD name, roles WITH * WHERE name contains 'custom.listcity' RETURN *"

I received this output which illustrates that dbms.security.procedures.roles was not effective at allowing the lowlife role to use the custom.listcity procedure :

image

On the other hand, after editing the dbms.security.procedures.roles neo4j.conf line like this:

dbms.security.procedures.roles=apoc.broker.receive:lowlife

I ran

"CALL dbms.procedures() YIELD name, roles WITH * WHERE name contains 'apoc' RETURN *"

Which returned the following output illustrating that dbms.security.procedures.roles=apoc.broker.receive:lowlife worked properly in allowing the lowlife role to use the apoc.broker.receive procedure.:

image

Based on these results and other tests I did, it appears that there are a range of default procedures such as dbms.cluster.routing.getRoutingTable and custom procedures which dbms.security.procedures.roles is not capable of giving a role access to, but that there are other procedures such as apoc.broker.receive which roles can be given access to.

Versions

  • OS: Ubuntu 20.4
  • ONgDB 3.6.0
  • apoc 3.5.0.12

Any updates or assistance is greatly appreciated. You guys are doing great work, and I can't tell you how much I appreciate it.

@wtrevena wtrevena changed the title dbms.security.procedures.roles not working with ONgDB 3.6.0 from apoc 3.5.0.12 dbms.security.procedures.roles not working with custom procedures and dbms.cluster.routing in ONgDB 3.6.0 from apoc 3.5.0.12 Jul 23, 2020
@wtrevena wtrevena changed the title dbms.security.procedures.roles not working with custom procedures and dbms.cluster.routing in ONgDB 3.6.0 from apoc 3.5.0.12 dbms.security.procedures.roles not working with custom procedures and dbms.cluster.routing.getRoutingTable in ONgDB 3.6.0 from apoc 3.5.0.12 Jul 23, 2020
@wtrevena wtrevena changed the title dbms.security.procedures.roles not working with custom procedures and dbms.cluster.routing.getRoutingTable in ONgDB 3.6.0 from apoc 3.5.0.12 dbms.security.procedures.roles not working with custom procedures and dbms.cluster.routing.getRoutingTable in ONgDB 3.6.0 with apoc 3.5.0.12 Jul 23, 2020
@bradnussbaum
Copy link
Contributor

@wtrevena Thanks for the report. I will start looking into this. I have a 3.6.0.0 apoc release nearly ready and may try to reproduce this on that version.

@wtrevena
Copy link
Author

@wtrevena Thanks for the report. I will start looking into this. I have a 3.6.0.0 apoc release nearly ready and may try to reproduce this on that version.

Thank you very much for the help, I can't tell you how much I appreciate it. Please let me know if there is anything that I can do to clarify or assist you, I will be working on this non stop until I find a resolution.

@wtrevena
Copy link
Author

wtrevena commented Jul 23, 2020

@wtrevena Thanks for the report. I will start looking into this. I have a 3.6.0.0 apoc release nearly ready and may try to reproduce this on that version.

After doing some more digging, I am curious to what precise driver / processor is behind the translation of the neo4j.conf dbms.security.procedures.roles setting.

To re-illustrate, I ran

"CALL dbms.procedures() YIELD name, roles WITH * WHERE name contains 'dbms' RETURN *"

Which resulted in the following output in the terminal on the left with the associated neo4j.conf dbms.security.procedures.roles settings on the right.

tempsnip

This appears to confirm that the processor behind dbms.security.procedures.roles is capable of adding role based permissions to some of the procedures, and that it translates the stated arguments verbatim as it added the lowlife role twice to dbms.procedures which is representative of the repetitive arguments specified in the dbms.security.procedures.roles setting. It also ignored the dbms.queryJmx procedure in alignment with the behavior I am experiencing with my custom function and with the dbms.cluster.routing.getRoutingTable procedure.

I am attempting to troubleshoot this issue by analyzing how these procedures and their associated permissions are stored in the files in the /data folder, but I am having a difficult time finding an appropriate plugin / interpreter to view the data in /data/databases or in /data/cluster-state in an interpretable way. As a short term fix I was planning on editing the files manually, but I am not quite sure where to start as I can't seem to find an editor that can make sense of the files.

I am speculating that this phenomenon is occurring as a result of some base ONgDB processor which compiles the neo4j.conf file, unless this setting is specifically handled by the APOC plugin. This is purely speculatory, but could it be possible that the procedures that dbms.security.procedures.roles is adding permissions to are available right away, but the other procedures that are being missed are only available after the dbms.security.procedures.roles setting is already processed? I thought that this might be the case as one of the last procedures that I would imagine is defined would be the dbms.cluster.routing.getRoutingTable procedure as I thought that this might be generated as the cluster is being formed, and this is one of the ones being missed.

If you have any suggestions on what else I could explore to troubleshoot this issue I would greatly appreciate it.

@wtrevena
Copy link
Author

@wtrevena Thanks for the report. I will start looking into this. I have a 3.6.0.0 apoc release nearly ready and may try to reproduce this on that version.

Good afternoon Brad, if you have any updates on this it would be greatly appreciated. As a result of this issue we couldn't identify any alternatives other than handling all database writes through an additional cluster of Nginx + uWSGI + Flask Python servers (mobile device -> Flask server -> ONgDB) because without restricting users to specific procedures with this feature, we can't prevent someone who obtains write credentials from sending something such as MATCH (n) DETACH DELETE (n) to the database. We are building a mobile application where generic neo4j user credentials will be stored on the client's device, and if we store credentials with unlimited write access anyone who cracks the device and finds the credentials could delete or mutate anything. This is introducing a substantial amount of complexity and overhead into our system, and if there is anything that we can do to help address this issue please let us know.

@ddayto21
Copy link

@bradnussbaum @wtrevena +1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants