I want to add some special checking to prevent direct, through the web access to authenticated users who, I discover, can get a second browser window and move around the site from URL independent of access path. Suppose I have pages stored in a folder structure rooted at /foo. The view security permission on /foo/... requires an Authenticated User. Normally pages are served from /foo/... under programatic control and additional constraints are applied. But, if the user creates another browser window and if he/she knows the URL (or the root URL) they can move about /foo/... however they want by simply entering the URL into the browser. (This works because they are authenticated and the authentication is shared in the browser.) An access rule seems to be the right mechanism for this sort of test, but I don't quite understand how to manage the control flow. I put the access rule in /foo. It gets executed when /foo is traversed. Now, it appears that the access rules are executed for side-effects only. If that's the case, the way an error message is returned to the caller is by modifying REQUEST to reference the error message object and not the object originally specified. Returning without changing the REQUEST allows Zope to continue traversing the path. Is my model correct?
Dennis Allison wrote:
Suppose I have pages stored in a folder structure rooted at /foo. The view security permission on /foo/... requires an Authenticated User. Normally pages are served from /foo/... under programatic control and additional constraints are applied. But, if the user creates another browser window and if he/she knows the URL (or the root URL) they can move about /foo/... however they want by simply entering the URL into the browser. (This works because they are authenticated and the authentication is shared in the browser.)
So, why is that a problem? You can't stop that with access rules anyway, you can't stop anything with access rules, users can choose to disable them on a whim. -- Jamie Heilman http://audible.transient.net/~jamie/ "I was in love once -- a Sinclair ZX-81. People said, "No, Holly, she's not for you." She was cheap, she was stupid and she wouldn't load -- well, not for me, anyway." -Holly
Duh.. you are right. It is vulnerable to several possible attacks-- a backdoor access controlling environment variable, explicit deletion through the ZMI (I think that'll work--but I've not tried), and so forth. Maybe you can propose a better solution. I have material which is to be revealed only at the right time and place. For example, tests and their answers. Our authentication is for the role and we (try to) manage access control on the other parameters explictitly in Zope code. How do we prevent end-round access? On Fri, 30 Apr 2004, Jamie Heilman wrote:
Dennis Allison wrote:
Suppose I have pages stored in a folder structure rooted at /foo. The view security permission on /foo/... requires an Authenticated User. Normally pages are served from /foo/... under programatic control and additional constraints are applied. But, if the user creates another browser window and if he/she knows the URL (or the root URL) they can move about /foo/... however they want by simply entering the URL into the browser. (This works because they are authenticated and the authentication is shared in the browser.)
So, why is that a problem? You can't stop that with access rules anyway, you can't stop anything with access rules, users can choose to disable them on a whim.
-- Jamie Heilman http://audible.transient.net/~jamie/ "I was in love once -- a Sinclair ZX-81. People said, "No, Holly, she's not for you." She was cheap, she was stupid and she wouldn't load -- well, not for me, anyway." -Holly
_______________________________________________ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
On Fri, 2004-04-30 at 18:28, Dennis Allison wrote:
I want to add some special checking to prevent direct, through the web access to authenticated users who, I discover, can get a second browser window and move around the site from URL independent of access path.
Suppose I have pages stored in a folder structure rooted at /foo. The view security permission on /foo/... requires an Authenticated User. Normally pages are served from /foo/... under programatic control and additional constraints are applied. But, if the user creates another browser window and if he/she knows the URL (or the root URL) they can move about /foo/... however they want by simply entering the URL into the browser. (This works because they are authenticated and the authentication is shared in the browser.)
True. Although. They don't have to open a second browser window, they can just type the URL into the original one, no? Are you doing some sort of client-side obfuscation by hiding the URL bar or something via JavaScript in the application?
An access rule seems to be the right mechanism for this sort of test, but I don't quite understand how to manage the control flow. I put the access rule in /foo. It gets executed when /foo is traversed. Now, it appears that the access rules are executed for side-effects only. If that's the case, the way an error message is returned to the caller is by modifying REQUEST to reference the error message object and not the object originally specified. Returning without changing the REQUEST allows Zope to continue traversing the path.
Is my model correct?
It's hard to tell. If you are relying on client-side security/obfuscation, you're fighting an uphill battle. You're never going to be able to prevent people from accessing a URL directly. If you aren't, it's possible that you may be "fighting the framework" a little bit here and should maybe take a step back and see if there's a way to solve the problem using the builtin Zope security model. - C
On Fri, 30 Apr 2004, Chris McDonough wrote:
On Fri, 2004-04-30 at 18:28, Dennis Allison wrote:
I want to add some special checking to prevent direct, through the web access to authenticated users who, I discover, can get a second browser window and move around the site from URL independent of access path.
Suppose I have pages stored in a folder structure rooted at /foo. The view security permission on /foo/... requires an Authenticated User. Normally pages are served from /foo/... under programatic control and additional constraints are applied. But, if the user creates another browser window and if he/she knows the URL (or the root URL) they can move about /foo/... however they want by simply entering the URL into the browser. (This works because they are authenticated and the authentication is shared in the browser.)
True. Although. They don't have to open a second browser window, they can just type the URL into the original one, no? Are you doing some sort of client-side obfuscation by hiding the URL bar or something via JavaScript in the application?
The first round of defense is to kill the URL bar (and rejoice in the additional screen real estate).
An access rule seems to be the right mechanism for this sort of test, but I don't quite understand how to manage the control flow. I put the access rule in /foo. It gets executed when /foo is traversed. Now, it appears that the access rules are executed for side-effects only. If that's the case, the way an error message is returned to the caller is by modifying REQUEST to reference the error message object and not the object originally specified. Returning without changing the REQUEST allows Zope to continue traversing the path.
Is my model correct?
It's hard to tell. If you are relying on client-side security/obfuscation, you're fighting an uphill battle. You're never going to be able to prevent people from accessing a URL directly. If you aren't, it's possible that you may be "fighting the framework" a little bit here and should maybe take a step back and see if there's a way to solve the problem using the builtin Zope security model.
The basic problem is simple--consider tests. We want them hidden until the test is about to be given and then available. Answers (for self-test exercises) should be available only after the corresponding test has been taken. (-: The current system controls access programatically, but it's possible to end-round the programs by typing the URL directly into the browser (after acquiring an appropriate browser window--one with a URL bar). It's this non-authorized access that we want to prevent. Any thoughts.
On Fri, 30 Apr 2004, Chris McDonough wrote:
On Fri, 2004-04-30 at 18:28, Dennis Allison wrote:
I want to add some special checking to prevent direct, through the web access to authenticated users who, I discover, can get a second browser window and move around the site from URL independent of access path. [...] you aren't, it's possible that you may be "fighting the framework" a little bit here and should maybe take a step back and see if there's a way to solve the problem using the builtin Zope security model.
There is one way, but the option of 10000 or more roles boggles the imagination.
I think (if I understand it right), I would suggest that: - There be a "big red button" that the proctor can push at the start of the test that goes and munges the role-permission map of the object(s) which comprise the test, maybe granting "View" access to "Authenticated" at that time. Before that, "View" would be restricted to "Manager". Alternately if there is no proctor, do it via a timed event (maybe an XML-RPC call via a cron job). - The "finish taking this test" button when pressed would cause the application to a) "lock" the test results (the user can't edit the answers anymore, even if he backs up in the browser) and b) "unlocks" the answers (by granting the submitting user the "View" local role on the object that comprises the results). This of course implies that the tests, test results, and answers are factored into separate objects. On Fri, 2004-04-30 at 19:38, Dennis Allison wrote:
On Fri, 30 Apr 2004, Chris McDonough wrote:
On Fri, 2004-04-30 at 18:28, Dennis Allison wrote:
I want to add some special checking to prevent direct, through the web access to authenticated users who, I discover, can get a second browser window and move around the site from URL independent of access path. [...] you aren't, it's possible that you may be "fighting the framework" a little bit here and should maybe take a step back and see if there's a way to solve the problem using the builtin Zope security model.
There is one way, but the option of 10000 or more roles boggles the imagination.
_______________________________________________ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
Good thought, but it doesn't fit the dynamics of the situation and does not scale. I'm still thinking a path based access permissions approach ought to work provided the access controls are hard to disable and provided the number of legal access paths is relatively small. Any thought or suggestions gratefully received. On Fri, 30 Apr 2004, Chris McDonough wrote:
I think (if I understand it right), I would suggest that:
- There be a "big red button" that the proctor can push at the start of the test that goes and munges the role-permission map of the object(s) which comprise the test, maybe granting "View" access to "Authenticated" at that time. Before that, "View" would be restricted to "Manager". Alternately if there is no proctor, do it via a timed event (maybe an XML-RPC call via a cron job).
- The "finish taking this test" button when pressed would cause the application to a) "lock" the test results (the user can't edit the answers anymore, even if he backs up in the browser) and b) "unlocks" the answers (by granting the submitting user the "View" local role on the object that comprises the results).
This of course implies that the tests, test results, and answers are factored into separate objects.
On Fri, 2004-04-30 at 19:38, Dennis Allison wrote:
On Fri, 30 Apr 2004, Chris McDonough wrote:
On Fri, 2004-04-30 at 18:28, Dennis Allison wrote:
I want to add some special checking to prevent direct, through the web access to authenticated users who, I discover, can get a second browser window and move around the site from URL independent of access path. [...] you aren't, it's possible that you may be "fighting the framework" a little bit here and should maybe take a step back and see if there's a way to solve the problem using the builtin Zope security model.
There is one way, but the option of 10000 or more roles boggles the imagination.
_______________________________________________ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
On Fri, 2004-04-30 at 21:31, Dennis Allison wrote:
Good thought, but it doesn't fit the dynamics of the situation and does not scale.
OK. I'm not sure of the requirements, so I can't really comment further.
I'm still thinking a path based access permissions approach ought to work provided the access controls are hard to disable and provided the number of legal access paths is relatively small.
I have no idea what this means, sorry. ;-) - C
On Fri, 30 Apr 2004, Chris McDonough wrote:
I think (if I understand it right), I would suggest that:
- There be a "big red button" that the proctor can push at the start of the test that goes and munges the role-permission map of the object(s) which comprise the test, maybe granting "View" access to "Authenticated" at that time. Before that, "View" would be restricted to "Manager". Alternately if there is no proctor, do it via a timed event (maybe an XML-RPC call via a cron job).
- The "finish taking this test" button when pressed would cause the application to a) "lock" the test results (the user can't edit the answers anymore, even if he backs up in the browser) and b) "unlocks" the answers (by granting the submitting user the "View" local role on the object that comprises the results).
This of course implies that the tests, test results, and answers are factored into separate objects.
On Fri, 2004-04-30 at 19:38, Dennis Allison wrote:
On Fri, 30 Apr 2004, Chris McDonough wrote:
On Fri, 2004-04-30 at 18:28, Dennis Allison wrote:
I want to add some special checking to prevent direct, through the web access to authenticated users who, I discover, can get a second browser window and move around the site from URL independent of access path. [...] you aren't, it's possible that you may be "fighting the framework" a little bit here and should maybe take a step back and see if there's a way to solve the problem using the builtin Zope security model.
There is one way, but the option of 10000 or more roles boggles the imagination.
_______________________________________________ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
On Fri, 30 Apr 2004, Chris McDonough wrote:
On Fri, 2004-04-30 at 21:31, Dennis Allison wrote:
I'm still thinking a path based access permissions approach ought to work provided the access controls are hard to disable and provided the number of legal access paths is relatively small.
I have no idea what this means, sorry. ;-)
Neither do I )-: I think I was confused and therefore confusing. Let me try to explain again. I am trying to control the publishability (that is, visibility) of objects A, B, and so forth. Object A has a URL /z/y/x/A and is legally referenced only from URLs /p/d/q/R and /p/d/n/S and then only in some (computed) circumstances. For our purposes let's assume that references from R and S can be guaranteed legal. All other reference are to be disallowed, even if the user holds the appropriate Zope permissions. The question is how to implement this functionality in Zope.
On Fri, 2004-04-30 at 22:44, Dennis Allison wrote:
I think I was confused and therefore confusing. Let me try to explain again. I am trying to control the publishability (that is, visibility) of objects A, B, and so forth. Object A has a URL /z/y/x/A and is legally referenced only from URLs /p/d/q/R and /p/d/n/S and then only in some (computed) circumstances. For our purposes let's assume that references from R and S can be guaranteed legal. All other reference are to be disallowed, even if the user holds the appropriate Zope permissions.
You could build a graph, which could be a fully predefined mapping from each "protected" object path (you'll want to think of this in terms of object path rather than URL as objects can be accessed via more than one URL) to a set of prerequisite "protected" object paths, maybe in a Python Script. As the user visits a protected object, the prerequisites for the object would be checked against a list of visited paths kept in his session, and if they aren't met, an error would be raised. If they are met, the path to the object is would be entered in the same visited path list in the session and he would be allowed to see the rendered object. And so on. The graph itself could be mutated when the user "finishes a test" and can see the answers so they weren't allowed to go back to the test questions and submit them again. But if you use sessions, you are implicitly depending on state that is kept on the browser, so this isn't very secure (if they click fast through the test, get to the answers, read them, close the browser and reopen it to get a different session, they could just take the test again; you can probably come up with other black hat scenarios). It would be better to associate the state with the username on the server side instead of associating a state with a session, but there is nothing really built in to Zope that will help you do this without some custom likely-non-TTW code. All that said, building these granual per-path state graphs will likely be tedious and whoever does it will be prone to error. There are actually probably a lot fewer states than this graph might indicate. You should try to find the states implied by the application, and maybe instead of using object paths, use state names like "taking test" and "finished taking test" and map each one of those names to a container that is allowed to be accessed while the user is in that state, which would imply that the user could also see the contents of the container. Or something like that. It's all pretty application-dependent. If you do this, you're essentially replacing Zope declarative security with a custom state-based model, so there are really no sane declarative security settings for the domain objects. You'll probably end up making them anonymously viewable in the ZMI and rely on your app code to do the security checks. All of this might be the right thing to do in your case as you're under a deadline and it sounds like you're developing this using mostly TTW code, but it seems like a lot of work to me. - C
Thanks for the thoughtful response. We use a mix of DTML/Python/Products as needed. It's proven to be a fairly fast, effective, and stable approach. We've handled whatever performance issues there might be by simply using big cheap iron. I think we will need to do a custom product. One thing I did not mention is that the materials to be protected are maintained in the local file system and are actually accessed through the LocalFileSystem product. The systems architecture limits the number of access points. A specialized product which has no URL access would serve our purposes, provide the security we want, and may even improve performance. Jaime suggests something along the same lines. For the moment I have found a couple of hacks that provide some limited protection although any self-respecting blackhat could slip through. We'll implement them immediately and then do a product. (The product shouldn't be much code, but it will need to have the *right* primitives--and that's the hard part.) Thanks for your help. On Sat, 1 May 2004, Chris McDonough wrote:
On Fri, 2004-04-30 at 22:44, Dennis Allison wrote:
I think I was confused and therefore confusing. Let me try to explain again. I am trying to control the publishability (that is, visibility) of objects A, B, and so forth. Object A has a URL /z/y/x/A and is legally referenced only from URLs /p/d/q/R and /p/d/n/S and then only in some (computed) circumstances. For our purposes let's assume that references from R and S can be guaranteed legal. All other reference are to be disallowed, even if the user holds the appropriate Zope permissions.
You could build a graph, which could be a fully predefined mapping from each "protected" object path (you'll want to think of this in terms of object path rather than URL as objects can be accessed via more than one URL) to a set of prerequisite "protected" object paths, maybe in a Python Script. As the user visits a protected object, the prerequisites for the object would be checked against a list of visited paths kept in his session, and if they aren't met, an error would be raised. If they are met, the path to the object is would be entered in the same visited path list in the session and he would be allowed to see the rendered object. And so on. The graph itself could be mutated when the user "finishes a test" and can see the answers so they weren't allowed to go back to the test questions and submit them again.
But if you use sessions, you are implicitly depending on state that is kept on the browser, so this isn't very secure (if they click fast through the test, get to the answers, read them, close the browser and reopen it to get a different session, they could just take the test again; you can probably come up with other black hat scenarios). It would be better to associate the state with the username on the server side instead of associating a state with a session, but there is nothing really built in to Zope that will help you do this without some custom likely-non-TTW code.
All that said, building these granual per-path state graphs will likely be tedious and whoever does it will be prone to error. There are actually probably a lot fewer states than this graph might indicate. You should try to find the states implied by the application, and maybe instead of using object paths, use state names like "taking test" and "finished taking test" and map each one of those names to a container that is allowed to be accessed while the user is in that state, which would imply that the user could also see the contents of the container. Or something like that. It's all pretty application-dependent.
If you do this, you're essentially replacing Zope declarative security with a custom state-based model, so there are really no sane declarative security settings for the domain objects. You'll probably end up making them anonymously viewable in the ZMI and rely on your app code to do the security checks.
All of this might be the right thing to do in your case as you're under a deadline and it sounds like you're developing this using mostly TTW code, but it seems like a lot of work to me.
- C
Dennis Allison wrote:
Good thought, but it doesn't fit the dynamics of the situation and does not scale. I'm still thinking a path based access permissions approach ought to work provided the access controls are hard to disable and provided the number of legal access paths is relatively small.
Well if you want to secure access rules further I threw a patch into the collector ages ago to remove the silly traversal stack semaphore, its in there somewhere, but if it was me I'd probably write a custom product for something like this. You need 1 object that can identify a user, their state, and control the logic behind what they are presented with next. While that object probably needs to be traversable, there's no reason the objects representing your data (the tests/answers) need be. -- Jamie Heilman http://audible.transient.net/~jamie/ "Most people wouldn't know music if it came up and bit them on the ass." -Frank Zappa
Yes, I think a custom product is likely to be the right route. Unfortunately the security problem is a real problem and we are on a deadline. But that's hardly new. Thanks for your help and for the reminder about the security issues around access rules. On Fri, 30 Apr 2004, Jamie Heilman wrote:
Dennis Allison wrote:
Good thought, but it doesn't fit the dynamics of the situation and does not scale. I'm still thinking a path based access permissions approach ought to work provided the access controls are hard to disable and provided the number of legal access paths is relatively small.
Well if you want to secure access rules further I threw a patch into the collector ages ago to remove the silly traversal stack semaphore, its in there somewhere, but if it was me I'd probably write a custom product for something like this. You need 1 object that can identify a user, their state, and control the logic behind what they are presented with next. While that object probably needs to be traversable, there's no reason the objects representing your data (the tests/answers) need be.
-- Jamie Heilman http://audible.transient.net/~jamie/ "Most people wouldn't know music if it came up and bit them on the ass." -Frank Zappa
_______________________________________________ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
participants (3)
-
Chris McDonough -
Dennis Allison -
Jamie Heilman