History for ServerSideTrojan
??changed:- Server side trojan issue Description Zope provides several object types that may be thought of as "executable" content. !DTMLDocuments, !DTMLMethods and !SQLMethods are examples of executable content. Under the current Zope security model, a !DTMLMethod author can create a method containing code that attempts to perform actions above the author's level of privilege. If the author attempts to run this method, he will get an error because he is not sufficiently privileged to perform the actions. However, if the author can arrange for a more privileged user to view his content, the code *will run*, possibly performing actions without the higher-privileged user even knowing about it. This hole results from the fact that !DTMLMethods execute with the privileges of the user *executing* the method. Who is affected Any site that allows untrusted users to create or edit "executable" content (DTML Documents, DTML Methods or SQL Methods currently) could be affected by this problem. Operational measures Zope 2.2 will contain changes to prevent this issue. In the meantime, managers of potentially affected sites should take some operational precautions to reduce their risk. o Do not view untrusted content while logged in with privileges that could be abused and **always** end your session with those privileges as soon as your work is done. o Create temporary users with "just enough privilege" to do a particular task and perform as much work as possible with these restricted privilege users. o Turn off javascript in your browser while administering the site! o Keep an eye on your site for suspicious activity - looking at the "undo" tab on the top-level folder of your site is a good way to get an idea of who has been doing what. o Keep good backups (which you should of course do anyway), and if possible avoid packing your site - that will give you most options for undoing site changes if you need to. Solution In Zope 2.2.0, the security model will be changed to prevent this issue. When executing, an executable (an object that executes logic supplied through the Web) will provide access to a protected resource only if the resource is accessible to both the user running the executable and to the *owner* of the executable. Huh, "owner"? That's right, we are finally going to define honest to God owners. For starters, when an executable is created by a authenticated user other than the superuser, the authenticated user will become the owner of the executable. An executable is created when someone adds one or when one is copied or imported. Note that the superuser cannot be an owner. Furthermore, the superuser is (as of 2.2) not allowed to create, copy, or move objects. In effect, we are diminishing the role and capabilities of superuser. The superuser should only be used for creating new users, including users with management responsibilities and for fixing up permissions that might be set incorrectly or maliciously by ordinary users. The executable will not store a direct reference to the owner. Rather, a tuple consisting of the physical path to the owner's database and the id of the owner within the database will be stored. When an actual owner is needed at run-time, the user database path and the owner id will be used to look up the owner. What is the relationship between the owner and owner roles? They are mostly independent. Whenever an owner is changed, the new owner will get the owner role on the object. The exception is the unlikely case in which the new owner is the special user nobody. The nobody user never gets the owner role. Only one user can be the owner. Many users can have the owner role. Owner roles can be changed without changing the owner. There is a tradeoff between the possible confusion of the two terms, "owner" and "owner role", and the use of a non-standard term (e.g. "responsibility") for something that most people think of under the word ownership. After some angst, it was decided that the terms "owner" and "owner role" are sufficiently distinct. Clearly they are similar and related. When an object is created, the creating user is the owner and is the only person who has the owner role. They are allowed to delegate ownership duties by giving others the owner role, but this is fairly rare in practice. What else does ownership mean? All Zope objects may be owned. Currently, ownership is most meaningful for executable objects, since ownership constrains the access that they have. The ownership of collection objects will be acquired by sub-objects, where possible. What happens if the owner goes away? What if someone deletes the owner from the user database, or deletes the user database? If the owner can't be found, then we'll use the special user 'nobody', which is extremely unprivileged. Question Does this also apply to the case where an object is referenced from a side of the tree where the owner doesn't exist? Answer -- No. The owner is not acquired. It is stored as the *absolute* path to the user database and a unique id. So, unless the owner has moved or gone away, we can still find the owner. Of course, the owner may have no privilege to access protected resources in the side tree. Say I'm in '/a/b', and I do 'var "a.c.std_header"', which is owned by someone in '/a/c'. But I only exist in '/a/b'. What happens? Answer -- It depends on what you try to do. If std_header is unprotected and only accesses unprotected resources, then there is no problem. Otherwise, the access will be unauthorized. Can the owner be changed? Yes. Those users having the "Take ownership" permission will be able to take ownership of objects using a new "Ownership" tab in the Zope management interface. Note that ownership may not be given away, only taken explicitly. How does the superuser fit in? The superuser is never an owner. The superuser is prohibited from adding (or copying, moving, or importing) objects. Question -- What about objects that are created by the "system"? For instance, a !ZClass that is installed by a product automatically. Who owns this? Answer -- No one. It is unowned, for two reasons: 1. Object in the control panel (e.g. !ZClasses) are never owned, 2. There is now a special user, system, that performs any operations done during startup. The system user is allowed to create objects and the objects created by the system user are either unowned or acquire their ownership from the place they are added. Another question: what about revisions? Let's say paul is a manager and jim is a manager. One day paul creates 'foo'. Then jim comes along and edits it. Who is the owner of foo? Who is the owner of the previous revision of foo? Answer -- paul. Ownership is unaffected by editing. A user must explicitly take ownership of an existing object to become its owner. ChrisW -- hang on. Doesn't this introduce the original problem again? What if jim was only an owner? He introduces a trojan *by editing the object*(which he doesn't have rights to execute, but Paul (the owner, even after edit) does), then the next time someone with sufficient rights to execute the trojan views the document, the trojan gets executed as before (because Paul, the owner, has rights to execute the code as he's a manager)? ZifNab -- I'm not sure, but you can only be an owner if your an authenticated user. As far as I understood, 'nobody' isn't an authenticated user. Thus the trojan will not be executed, because it hasn't got an owner? Am I right here? Of course, you've to trust your authenticated users. Or am I wrong again here? ChrisW -- I may be wrong but I thought the problem was authenticated users, who didn't have sufficient right, adding trojans which got successfully executed when someone who *did* have sufficient rights viewed them? If so, then I think the situation I describe above is correct. Answers to ZifNab's questions: - The trojan will have an owner, Jim, because ownership is unaffected by editing. - I wouldn't trust most authenticated users ;-) GvR -- this is a standard issue with set-uid programs in Unix. The standard solution is: don't give permission to edit executable objects to users who you wouldn't trust executing them. There's really nothing else you can do... Handling of unowned executables If an unowned executable is called directly or indirectly from another executable, then the executable can access resources as long as the person running the executable can. In other words, the behavior is the same as for Zope 2.1.6 and earlier. If an unowned executable is called from an owned executable, then the unowned executable operates as though it had the owned executable's owner. Question -- Couldn't someone get the same TrojanHorse functionality just by contriving for a dtml method to be unowned? Answer -- It isn't possible to contrive to make an object [74 more lines...]