[Grok-dev] Data modelling & security
Matthias
nitro at dr-code.org
Sun Jan 16 20:34:41 EST 2011
I have a few fundamental question how to model and retrieve my data from
the ZODB in a secure way.
I'll make a very simple example case so it's not too abstract:
Let's say my application is a simple task planner. There are Task objects
and User objects. Then there's a relationship object called Assignment
which takes a task and a user. It basically says "Task T is assigned to
User U". Tasks have a "dueDate" and users have "name" and "password"
attributes.
Furthermore Tasks, Users and Assignments can be protected with permissions.
Now a user might perform a query like "for tasks which are due tomorrow
get the task and its assigned users". That'd be useful to fill your
client-side "todo list" widget for example. The query as seen from a
security point of view:
Desired query results
(x means accessible, - means inaccessible):
Task User Assignment Result
------------------------------------------------
- - - nothing
x - - Task, but not user
x x - Task, but not user
x - x Task, but not user
- x - nothing
- x x nothing
- - x nothing
x x x Task and user
Alternative:
Task User Assignment Result
------------------------------------------------
- - - nothing
x - - Task, but not user
x x - Task, but not user
x - x Task, but dummy user
- x - nothing
- x x dummy task, user
- - x dummy task, dummy user
x x x Task and user
Dummy objects are basically just empty "Unknown/Protected" objects.
Second alternative:
Raise exception as soon as forbidden data is encountered. Not really
viable imo.
Problems:
1) Does the basic version or the alternative version make more sense? The
alternative version clearly marks any missing data. I am not sure if
that's good or bad.
2) Each intermediate query result would need to be security checked. If
you think checking the resulting objects sufficed, just imagine the
results of the following query: "get any user where task == 'top secret'".
You'd get a list of users involved with that task even if though nobody
should've known that those users were assigned to the task.
3) Resulting from 2) there might arise performance problems. I am not sure
if the query could be performed while collecting the necessary permissions
for each "row" in the result. Then one could check permissions only at the
end (and possibly against some form of index to speed things up or the
"top 10" of the results).
4) If a user is generally accessible, it should not return the "password"
attribute of the User except if the user is the querying user. I guess
this can be solved with zope.proxy/zope.security. Or by turning the
password attribute to a "PasswordProtected" relation between a user and
its password, then the relation can be protected at the object level, just
like the Assignment
How do you guys deal with these problems? I'd really like avoid having to
write a special grok.View and explicitly checking permissions for each
operation the client might perform. If the queries could be all dynamic I
could a) develop faster, b) had less redundant code and c) clients could
create their own UIs/queries for their tasks.
Additionally, are there any comparable systems which feature full objects
like the ZODB does, yet allowing fully dynamic queries with fine-grained
security? It might be worth "stealing" from them :-)
Is it even advisable to be able to query the ZODB in the way outlined
above?
Finally, is anybody else interested in features like this? Right now it
seems this could make your client side coding a lot easier, especially if
you have generic javascript widgets for lists, tables, forms and so on.
-Matthias
More information about the Grok-dev
mailing list