Client side trojan issue
Description
    Imagine you have some kind of system that you administer through a 
    web GUI, such as HotMailx, your Netscape Admin server or a site
    like Zope.org.  You get in to work and use this service for a while
    (check your mail, manage your servers, whatever). For our example, 
    lets say you were using the netscape admin server. 
    Later in the day someone sends you an email asking you to look at 
    a web page.  You go the page using the browser session where earlier 
    you had logged in to the admin server. However, the page does a 
    redirect to a url of your admin server that causes your main web 
    server to be deleted! The redirect will succeed, as you've already 
    logged in to the admin server earlier with sufficient privileges to
    delete your server. 
    There are a few variations on this theme, involving JavaScriptx that 
    can silently submit a hidden form to do the same sort of thing. It 
    appears that most web applications involving authentication are 
    vulnerable to this sort of attack.  
    Web clients will cache your credentials and send them automatically 
    to a realm that you have visited earlier in the session, which in a 
    stateless system is a reasonable behavior. The problem is that the 
    client is also willing to let almost any page on the Web take actions 
    automatically on your behalf through the use of things like redirects 
    or javascript code.  
An Example
    Lets say I know that you run a web server that includes a through-
    the-web management server on your site (such as NS Enterprise 
    Server). I can probably assume that you've used the default ports etc. 
    during installation.  
    If you've logged into the management server at some point during 
    the browser session and I can get you to view my HTML page during
    that same session, then there is a very good chance that I can 
    force you to unwittingly delete your main web server installation
    using a plain HTML form that submits itself (via javascript) as 
    soon as the document is loaded. That form is submitted to the 
    function of the management server that deletes the server.  
    Most browsers, when first installed, will pop up a dialog of some
    sort warning you when you are submitting form information. Most 
    browsers also give you the option of selecting "never bother me with
    this again" right on the dialog.  How many reading this have turned
    this off? A large number, I suspect (myself included). Because we
    cannot be bothered with those silly dialogs, we will all be in the
    same boat when our first clue that something is wrong will be 
    when we see the response from our management server (some variation
    of "Congratulations! You have deleted your entire main web site 
    successfully!").  
    We have verified that this attack works with some real-world tests
    involving NS enterprise server and some through-the-web mail services. 
    At this point, we highly suspect that almost any through-the-web 
    management system (including through-the-web management systems for 
    certain operating systems) is probably vulnerable to this sort of 
    trojan attack.  
    The amount of actual damage
    that could be done and the difficulty of knowing enough about the 
    environment to pull off an attack vary depending on the service in 
    question, but at best that is security-by-obscurity. Note that CERT
    has issued an advisory that touches on this in passing (noting the 
    possibility of using JavaScriptx or other scripting support to take
    actions on the users behalf without him knowing it):
    
    http://www.cert.org/advisories/CA-2000-02.html. 
    Coming up with a workable technical solution to this is tricky - there 
    is nothing in the current  Web infrastructure that deals with this 
    directly. Web clients and servers have a means of dealing with 
    authentication (are you really who you say you are?) and authorization
    (the server says "no, you are not allowed to do that"), but they do 
    not have a way of verifying intent ("do you really mean to delete
    your site, or has someone tricked you into this?"). 
Who is affected
    Potentially any Web-accessible system is vulnerable to this type of
    attack. 
Operational measures
    As noted below, we would very much like to come up with a solution 
    that either prevents or significantly reduces the risk of this type
    of attack. This Wiki will serve as an ongoing discussion toward that
    goal. In the meantime, managers of not only Zope sites but any Web-
    managed system should should take some operational precautions to 
    reduce their risk. 
Do not view untrusted content in any browser session where you have
      previously logged in to any web-based system with privileges that 
      could be abused. 
 
Turn off javascript! While it is not the only way, javascript is by
      far the easiest way for an attacker to make a Web client take actions
      on your behalf. 
 
The stakes are high
    There is a serious security problem here. Although it is not
    Zope's fault, it is a problem that Zope should deal with. 
    Because one of the cornerstones of the Zope philosophy is the
    ability to safely delegate responsibility, we don't feel that
    relying on operational security alone is an adequate answer. Our 
    goal is to come up with a solution to prevent or significantly 
    mitigate the risk of such an attack against Zope sites. 
Mitigation
    First, there probably isn't a "solution" to this problem.
    There are a variety of operational and technical strategies we can
    investigate to mitigate the risks. 
Mitigation 1, Curtail time logged in and activities
    This is an operational mitigation technique. 
    Never 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. 
    Variations: 
    Pros: 
-       p1.1
 Requires little or no software change.  
 
-       p1.2
 Works on non-Zope sites. 
 
Issues
-       i1.1
 By default, Zope doesn't provide a facility to log out, 
        other than re-booting your browser. :( This is true for any
        system that relies on basic authentication. 
 
-       i1.2
 This is very hard for the user to manage, especially
        web infrastucture.  There aren't good ways to control 
        privilege. There are many degrees of priviledge and in many
        applications, much useful functionality requires a level of
        priviledge which can be exploited to do harm. 
 
Mitigation 2, Undo
    This is an operational mitigation technique. 
    Undo provides a certain level of protection. 
    Pros: 
      See p1.1. 
-       p2.1
 Provides a way to recover from damaging scripts 
 
-       p2.2
 Unique to Zope 
 
    Issues: 
-       i2.1
 Doesn't work if a site doesn't support or allow undo. 
 
-       i2.2
 Doesn't work with non-undoable transactions, such as
        RDBMS transactions. 
 
-       i2.3
 Doesn't work if it involves objects that change often
        (e.g. the catalog). This can and should be mitigated
        by efforts to mitigate hot spots. 
 
-       i2.4
 Doesn't help with inherently non-undoable operations, like undo. 
 
-       i2.5
 It may not be possible for a user to know that they've been 
        hacked, so that may not know to undo. 
 
Mitigation 3, minimal referer checks
    For "unsafe" requests, the security machinery could attempt to get the
    HTTP Referer header from the request and determine if it seems to
    point to a local object. If not, the request will be denied. 
    An unsafe request is a request of a protected resource through a POST
    request or a GET request with a query string. 
    If necessary for xml-rpc or soap, we might allow a request to omit
    http referer if it has auth data in a form that would not be
    automatically provided by the browser. 
    If the referer does appear to be a local object, we look at the local
    object and see if it has an owner. If it does, then we only allow
    access of the owner would have access. For example, suppose you wrote
    a page that has a redirect to
    Members/jim/manage_deleteObjects?id:list=SomeObjectx?. Zope would see
    that your page was the referer and that it was owned by you. Since you
    don't have rights to run manage_deleteObjects in my folder, the
    request would be unauthorized. 
    In addition, if the object has (new) proxy roles, then they would
    apply too, so they could offer further protection. I can use (new)
    proxy roles to prevent you from shooting me with my own wiki. :) 
    Pros: 
-      p3.1
 Leverages existing client behavior to get the required meta
         data to ensure request propriety. 
 
-      p3.2
 Can likely be hidden behind the security policy abstraction,
       probably requires little or no user code changes. 
 
-      p3.3
 Leverages a unique feature of the (new) Zope security model,
         which is that we check the privileges of the owner of
         executables. 
 
    Issues: 
     i3.1 --How do you get into a protected resource if the referer has to
         be a local resource with a peer level of privilege? (The "entry
         point" problem). 
-          jim
 Put another way. How does someone get into the management
             interface in the first place? We need to distinguish bwteeen
             "safe" and "unsafe" management operations. I propose that, at
             least by default, that we only check HTTP_REFERER for POST
             requests and GET requests with form data. Perhaps there could
             be a way for the programmer to override this rule. 
 
-      i3.2
 It is not possible to say for sure that all browsers send the
         referer header. The conventional browsers seem to, so this
         probably isn't a big problem, though we should document which
         browsers we know we support. 
-          jim
 Right. You have to pay something, and this seems like a
             pretty small price to pay. Plus, keep in mind that we now
             allow people to replace our security policy with a different
             one and they'd be able to disable this feature if they felt
             it was too restrictive and were willing to bear the risk. 
 
-          mj
 Just listing browsers will not suffice. Junkbuster, a
            filtering proxy (which I use), filters out the referrer header.
            Documentation will have to make it clear that the referrer
            header is used and for administring Zope in a default install
            requires you to bypass such a proxy. However: some corporate
            firewalls also filter this out, and the end user doesn't always
            have control over this, nor over the Zope server he is
            administering. Think of an Intel employee becoming a member of
            Zope.org. 
 
 
-      i3.3
 Regardless of browser, users trying to access a Zope site may
         be coming in through a filtering proxy that either strips or
         provides bogus referrer information. This should be documented so
         that people are aware of the potential problem. 
 
-      i3.4
 Transitions from SSL to insecure connections will lose
         referrer information. This should be a pretty rare thing in
         practice, but could conceivably cause seemingly odd behaviors if
         sites are set up in mixed SSL/clear configurations, so it should
         probably be documented. 
 
-      i3.5
 All existing ZClientx? scripts will likely break unless we
         make changes to have the referrer set by the library itself
         (maybe we could set referrer to the actual target?) 
-          jim
 Or provided some other way to spell that they are
             special. Alternatively, we could provide another way for them
             to spell authentication data that isn't provided by browsers. 
 
 
-      i3.6
 Would break xml-rpc, soap and other protocols that piggyback
         over HTTP unless we provide for some kind of special handling of
         those protocols. 
-          jim
 This definately needs some thought. See above. In the
             short term, if we feel that xml-rpc can't be spoofed from
             HTML or java-script, we could simply not require the HTTP
             referer, but I think I'd rather just provide a different way
             to spell authentication data. 
 
 
-      i3.7
 May break existing applications, though the likelihood of
         this is hard to gauge. This is probably tolerable, since
         developers should be able to fix apps by changing ownership or
         other non- code changes. It is possible that the objects
         comprising the existing applications would become "unowned" when
         the security policy changes are applied, in which case there
         probably would be no breakage. 
-          jim
 Yes. Something we have to remember is that the stakes are
             high. We're going to have to be willing to give up something
             to get what we want. 
 
 
-      i3.8
 Can be defeated by Java-script, at least for within-site
        attacks. 
 
-      i3.9
 Security design becomes harder because one needs to
       consider security implications of hyperlinks (and forms). 
       For example, suppose I have an unprotected but highly
       priviledged (unowned or owned by a priviledged user) page that
       provides a form or a link to do something bad. Such a page
       could be exploited by a malicious unpriviledged page. 
 
Mitigation 4, referer checks and auto-logout
    The security machinery will attempt to get the HTTP Referer header
    from the request and determine if it seems to point to a local
    object.  If the referer is missing or is non local, then the user
    will be logged out. They can access the requested resource only if
    they provide new credentials. 
    If necessary for xml-rpc or soap, we might allow a request to
    omit http referer if it has auth data in a form that would
    not be automatically provided by the browser. 
    If the referer does appear to be a local object, we look at the 
    local object and see if it has an owner. If it does, then we only 
    allow access of the owner would have access. For example, suppose 
    you wrote a page that has a redirect to 
    Members/jim/manage_deleteObjects?id:list=SomeObjectx.  
    Zope would see that your page was the referer and that it was owned 
    by you. Since you don't have rights to run manage_deleteObjects in 
    my folder, the request would be disallowed.   
    In addition, if the object has (new) proxy roles, then they would 
    apply too, so they could offer further protection. I can 
    use (new) proxy roles to prevent you from shooting me with my own 
    wiki. :) 
    Pros: 
      See p3.1, p3.2, p3.3.  
-       p4.1
 Doesn't limit protection to POSTsx and GETsx with form data. 
 
-       p4.2
 Can't be defeated by Java-script 
 
    Issues: 
      See i3.2, i3.3, i3.4, i3.5, i3.6, i3.8, i3.9. 
-       i4.1
 What is a local object? It is tempting to say that it is
        an object that is outside the user's "realm", which might be
        the folder where their user folder is.  For now, an object is
        local if it's on the same (possibly virtual) Zope "site". 
 
-       i4.2
 How do you log someone out? 
-          Cookie-based authentication
 You simply expire the cookie and
           give them a login form.  When they submit the login form,
           they'll be coming from inside. (BTW, the login form should be
           clever enough to take them back to where they were trying to
           go.) 
           It might be a good idea to display a page first that
           explains what's happening and gives them the option
           of going forward. This way they could avoid logging our.
           Of course, Javascript could defeat this, but at least
           this would help with accidental logouts. 
 
-          Basic authentication
 tbd 
 
Paul
           How about, instead of logging someone out (unauthenticating 
           them), we unauthorize them until they perform some step to 
           get re-authorized? 
-            Jim
 On further reading and contemplation ..... 
             Maybe we should separate authentication from login
             and authorization.  This relates to the notion of
             controlling your own priviledge. Your notion of
             automatically reducing someone's priviledge is a special
             case.  Maybe we don't view "log-out" as a change in
             authentication, or authorization (sort-of, email
             is failing me). 
             "Logging" out can be viewed as stopping work in a
             priviledged session. It could be orthoginal to
             authentication.  Maybe you still know I'm Jim, but I
             don't want you to take anything I say seriously. 
             So, when we get a request from a funny place (or no
             place), we log someone out, without necessarily
             de-authenticating them. They must do something special to
             be able to start doing priviledged things again.
             The problem is that we need to make them, the human, do
             something that javascript can't fake. This is the hard
             part. It seems that the only way to be sure that
             they are realy doing something is to make them enter a
             secret that isn't available to javascript. 
             Using re-authentication is probably very problematic for 
             certificate authentication. 
I wonder if there is some way to fight Javascript
             with Javascript? I wonder if there is some Javascript
             thing that we could do that could ask the user to
             verify an action and that can't be subverted by attacking
             Javascript. 
 
 
 
-       i4.3
 It may be hard to allow someone to log in safely. For example,
        we might not want to return a login form to a frame in a
        malicious frame set, as java-script in the frame-set might be
        able to steal the password from the form. :( 
 
-       i4.4
 How do you get into a protected resource if the referer has
        to be a local resource with a peer level of privilege? (The
        "entry point" problem). 
-         Jim
 Put another way. How does someone get into a
          protected interface in the first place?  They have to 
          authenticate.  This hinges on the ability to log someone
          out when they come from the wrong place. 
 
-         Brian
 I just don't know if you can reliably tell the 
        difference in context. For example: My browser tries to 
        go to manage_main, sending no credentials and and empty
        (or offsite) referer. The system challenges me. My browser
        retries the request, sending my credentials and the same
        empty or offsite referer. Zope sees my bad referer, logs 
        me out, I get challenged again... ad infinitum. Note that I 
        am making an assumption here that the referer
        remains the same as the request that was initially challenged
        (or becomes undefined). We should verify that. 
-           Jim
 The change in context can be provided in two ways: 
            OTOH, it would be very nice if we didn't have to
            mix-up authentication with this, although I 
            don't see a way around it right now. See my response to
            Paul's comment in i4.2. 
 
 
 
-       i4.5
 UI's may need to be redesigned to make greater use of 
          frames. 
          Consider zope.org. An "unpriviledged" page, like a news item
          has links to priviledged pages, such as "Personalize". An
          attempt to follow such a link would fail. We would need to
          redesign this interface so that the menu was in a
          priviledged page in one frame, while the news item was in a
          separate page. 
-           Brian
 I don't think that this will actually solve the 
          problem. The referer when you click on a link in the frame
          will still be the actual page in the frame, not the frameset, 
          so the behavior would basically be the same as if frames were 
          not involved, wouldn't it? (unless you can design a site where
          the "privileged frame" can drive everything and you never have
          to click on a link in the "content" frame - that seems highly
          unrealistic to me though) 
 
 
Idea: 
-  Michael
 Can the code that generates a "genuine" form include some kind of ID code that changes? If the form is not submitted with a valid ID then it is rejected. The validity of the ID also times out after a specified period. 
  I have implemented a system like this in a login form in ColdFusionx. When the form is generated it includes a hidden, random ID. A copy of the ID is held in a CF session variable. When the form is submitted, the ID on the submitted form must match that held in the session var for the login attempt to succeed. Sessions in CF are relationships between a CF "application" on a server and a client. They time out after a specified period. Perhaps have one ID for a whole session instead of a different one every time the form is created. 
  Could a clever client-side trojan find one of those forms and read the ID from it? 
 
- Adamsc
 this is exactly the approach I outlined in response to a BUGTRAQ posting on the same subject. Since you've already had to build or use a session manager to handle the logins properly, you can use either the session identifier directly or a random session variable for authentication (e.g. modify.php?ID=1234&Confirmed=RANDOM_SESSION_ID). The only way someone could create the fake form would be figuring out the session identifier; if your session manager is buggy enough to allow that, the attacker could directly hijack your system anyway. 
 
- oliverb
 The http/1.1 rfc also mentions the problem of a client side trojan( rfc2616, 9.1.1). While they don't go into depth, perhaps it's worth to cite one or two sentences: 
    "Implementors should be aware that the software represents the user in
 their interactions over the Internet, and should be careful to allow
 the user to be aware of any actions they might take which may have an
 unexpected significance to themselves or others.
 In particular, the convention has been established that the GET and
 HEAD methods SHOULD NOT have the significance of taking an action
 other than retrieval. These methods ought to be considered "safe".
 This allows user agents to represent other methods, such as POST, PUT
 and DELETE, in a special way, so that the user is made aware of the
 fact that a possibly unsafe action is being requested." 
 So why not restrict the manage_* methods to just accept POSTedx requests. This wouldn't cure the problem of javascript, but the unsecurity of the client can't be the concern of the server side anyway.
  
 
  
      
       |