Discussions

J2EE patterns: Cross Domain Cookie Provider

  1. Cross Domain Cookie Provider (13 messages)

    Problem
    Cookie domains provide needed security constraints but also make it difficult to pass user specific state between web applications on multiple domains which do not share the same parent domain. For example, domain1.foobar.com can share a cookie with domain2.foobar.com if the cookie domain is “.foobar.com”. However, foobar.com cannot set a cookie with a domain of “.com” due to security constraints (often called the two dot rule).

    Forces
    Business stakeholders may associate a common domain with dilution of their brand image. Business stakeholders may prefer to maintain multiple “vanity” domains for customers even if they are served by the same web applications and back end systems.

    Applications will often be required to share user specific information across domains in the cases where business stakeholders require “vanity” domains.

    Current web infrastructure and software does not lend itself to transparently share user specific information across domains.

    Alternate Solutions
    URL rewriting or hidden fields are often used for this purpose, but implementations of these are often point to point integrations between applications. Point to point integrations using URLs and hidden fields are inherently error prone and inflexible. URLs are limited in their length. Also, if the user specific information contains personally identifiable information then it cannot be passed as a URL parameter and must be encrypted to protect user privacy. This may impose encryption even on pages which do not require the use of the personally identifiable information. Points to point integrations are also difficult to maintain because adding data often requires touching and retesting each and every integration point.

    Solution
    The Cross Domain Cookie web pattern defines a cross-platform, cross-language method of transporting user specific, non-volatile state between HTTP based systems which are accessed by the user through domains not sharing a common parent.

    This basic method has been in use since at least 1997, but so far has not been defined in a language and platform neutral manner. See: http://www.15seconds.com/issue/971108.htm

    The Sun Liberty project also defines a similar methodology:
    http://research.sun.com/Liberty/
     
    Structure
    Components
    Client: A client communicating using the HTTP protocol.

    Vanity Domains: customer facing domains which must share state but do not contain a common parent domain.

    Master Domain: a single domain on which the master cookie is created and propagated to vanity domains.

    Cross Domain Cookie: A cookie containing non-volatile data.

    Vanity Servers: Logical server(s) communicating using the HTTP protocol which creates cloned cookies in the vanity domain(s).

    Master Server: A logical server communicating using the HTTP protocol which generates the master cookie. This server must use a single master domain to generate the master cookie.

    Please note in the component definitions above that the Vanity and Master Servers may actually be referring to the same physical server at runtime. For security and abstraction purposes HTTP treats them as separate logical servers since they are on different domains.
    Activity
    1. Client sends a GET request to a vanity server.

    2. The first request from a particular client to a particular vanity server must use the HTTP GET method. After the following series of steps is executed once for the user in a particular vanity domain, there are no constraints on the HTTP method used for other subsequent requests.

    3. The vanity server receives the request and if a cloned cookie does not exist in it’s domain it issues an HTTP redirect to the master server using the master domain. The URL target of the redirect must contain a paramete indicating the original absolute URL that the client requested.

    4. If necessary, the master server receives the redirected request from the client and issues a redirect back to the vanity server (on the vanity domain) using the absolute URL request parameter from step 3. If the master cookie does not exist, the master server creates it. The redirect back to the original URL the client requested must contain an additional request parameter containing the data in the master cookie.

    5. If necessary, the vanity server receives the redirected request from the client containing the data from the master cookie as a parameter from 4. The vanity server uses the parameter data to create a clone of the master cookie in its vanity domain.

    6. Optionally, if the content of the URL containing the cookie value as a parameter is too long, the vanity server then issues a final redirect to the client which is targeted at the originally requested client URL without the cookie value parameter.

    Processing of the HTTP request then continues as normal on the vanity server, this pattern supports both internal processing and proxying of the request to an upstream server.

    Consequences
    + The master cookie propagates across all domains transparently to:
     * The end user
     * Downstream proxies
     * Any applications deployed on the vanity server(s)
     * Proxied servers upstream of the vanity server(s)

    - The cross domain cookie cannot contain any volatile information since there is no way to synchronize changes to the cross domain cookie data across domains.

    - There is additional network overhead because a separate IP connection is potentially required for the redirect in step 3. This only occurs when a user first accesses a new vanity domain. With the connection keep alive feature of HTTP 1.1 the overhead of the other redirects is minimal.

    Implementation Notes
    This pattern is useful for web single sign on, tagging a user across browser sessions, or providing a browser session identifier across domains.

    Consider a Servlet 2.3 Filter for easy and transparent implementation of the vanity server in your Java web apps.
  2. Just be careful with security...[ Go to top ]

    Having been using this technique for a while in web SSO/security apps, I do want to emphasize the security concerns introduced by this. As described, this is vulnerable to both hijacking (an attacker can pretend to be one of the vanity domains and coax your browser into revealing the value) and injection (an attacker can pretend to be the master and inject an unsolicited value into a vanity domain) of cookie values, and if you're using it for SSO as suggested, you're in for some big problems.

    You'll notice that the liberty specifications include mechanisms for signing requests and responses - this is absolutely critical if you're using this for any security application or in any other application where you're worried about data leakage or session hijacking.
  3. SSL[ Go to top ]

    Good point. I have always used a third party product such as SiteMinder to implement SSO. If you can't afford third party software, read on with caution...

    SSL should be used to set the cookies on the master and vanity ( and of course to perform the authentication ) to prevent the problems listed. Also, the SSO cookie should be a random GUID and should last only as long as the browser instance. Persistent cookies should not be used for SSO.

    Valid SSL certs are generated by a third party Certificate Authority (such as Verisign) so the user will get a prompt that a fake SSL cert cannot be verified if the server providing the cert is different than what is registered with the CA. Client side certificates can also be used as additional verification of the identitiy of the end user (or client side system).

    Please note that this does not mean your whole site has to be SSL! Only the interactions doing authentication and setting the SSO cookies must be SSL. Of course, if there is other data or services you do not want publicly available those should also be SSL.
  4. Is this what LTPA uses?
  5. Some of the security problems mentioned of session hijaking or injection can be overcome if you do away with the Master server. This is possible if there are only a fixed small set of vanity domains.

    This works as follows

    1. HTTP GET request received on domain abc.com . The server creates a unique SSO handle and persists it to a common shared database, along with user identification information. This handle is associated with the session cookie.

    2. A HTTP Redirect is sent to second vanity domain pqr.com. The redirect URL contains the SSO handle and the return URL of abc.com site.

    3. The vanity domain on pqr.com gets the SSO handle and looks up the user information from the shared database. If the lookup was successful, the user is automatically logged in to the site and a cookie is created.

    4. The domain pqr.com redirects back to abc.com

    5. When the user logs out on either of the two domains , the SSO handle is removed from the shared database.

    Of course, this is possible only if the number of vanity domains is low. (I have only seen implementations with 2 or 3 domains)

    ..
  6. We have implemented SSO the same way, for our product, with several modifications.

    A) The Pattern needs correction for the sake of security. It was, already, mentioned here that there is a security risk of hijacking login information. But the vulnerability can be removed. First - where is it introduced? In step 5:

    "5. If necessary, the vanity server receives the redirected request from the client containing the data from the master cookie as a parameter from 4. The vanity server uses the parameter data to create a clone of the master cookie in its vanity domain. "

    How to remove it? The Master server should not pass the authentication cookie via HTTP parameter.

    Master server should store the authentication cookie in some shared storage that only a group of pre-defined servers can access. It can be a database, clustered cache - whatever is convenient. In our case, we used clustered cache, for the performance reasons. In this case, Master server passes some temporary ID with which to look-up the "cookie" in the shared storage. After a Vanity domain reads the needed information from the shared storage, it removes it. As outside servers can not, by definition, access the shared storage - it is safe.

    B) In the pattern definition it was discussed how to log-in a user. However, that's not enough. In any practical implementation, it is, also, very important that when user logs-out on any Vanity Server - other servers to deauthenticate, as well. Because if a user expects SSO, sure thing s/he will expect Single Log Out (SLO) too.

    The problem with the SLO is that, after an SSO, each Vanity server has its own cookie, as described in the pattern and do not consult with the Master Server, any more - for performance reasons, you do not want every load of a web-page to involve an HTTP Redirect, that would break HTTP Post attempts, among the other things.

    The approach is the shared storage, again. When user log-out on any server, that server raises a flag in the shared storage, indicating that any cookie for a specified user created before the flag was raised, is presumed invalid and re-authentication must happen.

    Please, note that this does not necessarily mean user will be logged out. Maybe user had enough time to log-out and log-in again. In this case, re-authentication will show that user is still logged in. However, Vanity servers with old cookies must go through this step to make sure they are not dealing with stale information.
  7. how the other vanity servers know the session is loged out?
  8. Hi.
    how do you implement fail-over?
    as i understand it, the master server is one machine, and the master domain is fixed, so when it falls, there can be no cookie issuing.
    So, how do you implement fail-over?
    thanx,
    Jus
  9. Hi.how do you implement fail-over?as i understand it, the master server is one machine, and the master domain is fixed, so when it falls, there can be no cookie issuing.So, how do you implement fail-over?thanx,Jus
    No. Master Server does not have to be one physical machine. The main point is - it to be one domain. There are a lot of ways for how to attach one domain to a cluster of servers, if you need failover and/or load-balancing. Your options range from Apache mod_jk (software) to numerous hardware solutions.
  10. The article mentions the length limitation of URLs as negative point for URL-rewriting.
    However it says later on in Point 4 that the copied data of the master cookie should be transferred as an url parameter.
    So why transfer it as a parameter at all. Why not as a request attribute?
    Here we would not have any length limitations, would we?
    If so step 6 was completely obsolete.

    Anyway, I do NOT understand, why the vanity server ought to redirect to the client which is targeted at the originally requested client URL without the cookie value parameter at all if the URL is too long.
    In this case it would not be possible to share the state at all, would it? So an error page telling the user that the state could not be maintained would be more adequate here?

    Looking forward to your reply.

    Kind regards
    Matthias
  11. I believe point 4 says to transfer data as URL parameter bcoz of the fact that when your redirecting from one domain to another domain, it have to be get request and not post request, so you can't transfer hidden attributes.
  12. I have implemented several SSO implementations for large clients and the term "cookie" discounts it from the Enterprise language. What you've done here is provide bad, if not dangerous information or ideas to Enterprise level developers. That's not very professional in my opinion.

    The Security Assertion Markup Language was developed to rid the community of cookies for SSO. If you want federated SSO (across multiple domains) don't use cookies. So a pattern for cookies is almost a joke in my opinion.

    David L Whitehurst
  13. A lot of temper there, David! :)

    The "enterprise"-level blah blah, "large clients" usually call SSO, something quite different - they have legacy applications that they want to bring into single authentication flow.

    What was discussed here was cross-domain sign-on implementation for web-based systems _on the Internet_!!! I can not stress this enough, Intranet, where you can put your clients into certain constraints is not the same as the Internet. And on the Internet, the one and only authentication mechanism you got is - cookies, so - please :)

    This pattern is very elegant, valid, not insecure in the least and perfect for the domain of problems it addresses.
  14. Can reverse proxies pass inbound cookie values presented on their public interface to back end web servers in different domains?

    If so, what directives or and modules are used to accomplish this, and are there any examples I can look at.

    Best Regards,

    Bob