COMMAND

    "ClientSideTrojan"

SYSTEMS AFFECTED

    Many web based systems

PROBLEM

    Kragen Sitaker found  following.  Apparently  Zope and many  other
    web-based systems suffer from a confused-deputy problem:  browsers
    are willing to visit URLs and submit forms based on untrusted  web
    page  contents,  and  servers  are  willing to trust browsers that
    submit  forms  and  web  page  requests  when  they  include Basic
    Authentication or authentication cookies with those requests.

    The Zope page describing the problem is at

        http://www.zope.org/Members/jim/ZopeSecurity/ClientSideTrojan

    This is  sort of  a variant  of the  "cross-site scripting"  thing
    (CERT Advisory CA-2000-02), in that  it involves some of the  same
    mistaken trust relationships.   The browser trusts random  servers
    to  give  it  URLs;  the  URLs  tell  the  browser  to go to other
    servers; the other servers trust the browser.  In CA-2000-02,  the
    browser then has  some trust relationship  with the server,  which
    doesn't figure here.

    The Zope page doesn't include a lot of detail on how this could be
    used, but we can think there are essentially three cases:

    a- server  X  sends  you   an  evil  form  and  JavaScript    that
       automatically POSTs the form --- to server Y, which trusts your
       browser.
    b- server X sends  you a 30[12] Redirect  or a Refresh that  tells
       you to GET a page from server Y; GETting the page has some kind
       of evil side effect.
    c- server Z, who might be  totally innocent or might be server  X,
       sends you an innocent-looking  form that gets POSTed  to server
       X.  Server X 30[12] redirects to server Y; the innocent-looking
       form does something evil.
    d- server  Z sends  you an  innocent-looking, but  evil, form that
       gets POSTed to server Y.

    The irritation of this attack seems mainly to be that the attacker
    needs know no secret about the victim, and so the same attack will
    work equally for anyone authenticated to a particular service.

    Randomly submitting a dummy form then isn't enough, and the attack
    should be defanged for the cases:

        1. Redirect to a GET action
        2. Forced POST submission by Javascript
        3. Evil innocent-looking form

    But not of course in the general case for

        4. Browser is vulnerable to cross-site scripting

    If  random  Javascript  can  find  out  what's going on in another
    window you're just as doomed  as ever.  (Bonus points  for warning
    users on  login that  their browser  is vulnerable  based on their
    user-agent string  - is  there a  list of  historically vulnerable
    browsers anywhere?)

SOLUTION

    The solution to case (a) is  simple; turn off JavaScript.  If  you
    run a web site  that might be impacted  by this, force your  users
    to turn off JavaScript; don't let them into the site in the  first
    place if they have  it turned on.   This can be very  simple --- a
    one-line onLoad script on every page that redirects their  browser
    to a page that explains they must turn off JavaScript and why.

    The solution to  case (b) is  just as simple;  don't allow GET  to
    have  an  evil   side  effect,  even   if  the  user   does   have
    authorization.  This is usually a good idea anyway.  GET  requests
    should be idempotent,  and destructive operations  usually aren't.
    If there are GET requests that can do evil, someone could just  as
    easily link to them.

    The solution to  case (c) is  already in place,  and has been  for
    years:  when following redirects on POSTs, the browser should  use
    GET on the resource it's redirected to, not POST.

    The solution to case (d) is not quite clear.

    The Zope page describes a number of mitigating measures:

      - not viewing untrusted content when using a trusted browser (!)
      - turning off JavaScript (of course)
      - log  out of  sessions when  you can  (the Zope guys apparently
        don't know that sending a  403 response to a query  will cause
        most browsers  to ask  for a  username and  password again; if
        you  can  persuade  the  user  to  refuse,  the  browser  will
        generally have forgotten the username and password)
      - Referer checks, which unfortunately don't work universally

    Unfortunately, today's web leaks resource names --- URLs ---  like
    sieves,  and   so  it's   impossible  to   safely  use   URLs   as
    authenticators.   Specifically, proxies  save URLs,  so the  proxy
    owners know them; httpd logs  save URLs, so everybody at  your ISP
    knows  them;  and  browsers  send  URLs  in  Referer:  headers, so
    everybody you link to knows them.

    Given that it's common to issue some sort of session ID to a  user
    upon   login   (separate   from,   for   example,   a   persistent
    identification cookie),  and that  this won't  easily be available
    to an attacker, a  quick and obvious way  to kick this problem  in
    the nads would seem  to be to embed  the user's session ID  in any
    form resulting  in a  state change  in their  data (configuration,
    purchase, whatever).  Then,  compare that supplied ID  against the
    authenticated session ID before actioning a GET/POST request.