Saturday, March 07, 2009

OpenID association poisoning

As part of the OpenID protocol a relying party often establishes shared secrets (called ‘associations’) with identity providers that are used to verify identity assertions.  It occurred to me that an OpenID relying party might easily introduce a major security hole in the process of establishing an association that could allow identity spoofing.

Each association is assigned a handle, which is a name by which the relying party and the provider will refer to the shared secret in later transactions.  The potential security hole is possible because the Provider alone determines the association handle.  If the relying party is not careful in saving associations it creates, a rogue Provider could hijack another Provider’s association with the relying party and thereby gain the ability to assert the identity of any user from the other Provider.  Here’s a scenario:

  1. Victim hosts his identity with GoodOP, and has logged into a vulnerable RP and saved some private data.
  2. Hacker hosts EvilOP, which is a carefully contrived Provider rigged to hack into RPs.
  3. Hacker attempts to log into RP as any account hosted by GoodOP and can thereby discover the handle CompromisedHandle of the shared association between RP and GoodOP.
  4. Hacker instructs EvilOP to assign CompromisedHandle as the handle for the next association it creates with an RP.
  5. Hacker starts a login at RP with a Claimed Identifier that points at EvilOP.  The RP then establishes an association with EvilOP as a preliminary step to the login process. 
  6. EvilOP tells the RP of the new association and says the handle for it is CompromisedHandle
  7. RP is vulnerable and overwrites the shared secret it has with GoodOP with the new one it established with EvilOP.  Yet CompromisedHandle is still associated with GoodOP in the RP’s associations table.
  8. Denial of Service: The RP can no longer log in users from GoodOP, because the shared secret between them is wrong and the RP will reject identity assertions from GoodOP due to invalid signatures.
  9. Identity Spoofing: EvilOP now can write identity assertions on behalf of GoodOP such that RP thinks they are from GoodOP.  Hacker can use EvilOP to write assertions and log in as anyone who has an account with GoodOP.

The good news is that having come up with this possible security hole, I did a check of DotNetOpenId and Janrain’s OpenID Ruby library.  Neither one was vulnerable to this.  Since all of Janrain’s libraries are similar to each other, I ended my investigation because it was likely that all the other Janrain libraries were also secure in this regard. 

Still, this is another argument for web sites to use standard libraries for their OpenID support rather than trying to implement OpenID themselves.  There are just too many potential security holes for a webmaster to avoid them all unless authentication is truly his focus and passion.

2 comments:

  1. Step 7 is not possible? I'd guess the RP stores associations per OP, so an OP cannot overwrite any other OP's associations

    I don't know how step 3 would be possible. The Web browser will never be able to read the handle established between RP and GoodOP, isn't the association created in a HTTP connection directly between the RP and GoodOP.

    Even if the Hacker could read the association between RP and GoodOP, this association wouldn't be the same as the one between the victim and GoodOP, because GoodOP probably derive the handle from a signed hash of the username & random number & timestamp, or something like that? So the handle that EvilOP gets, would be different from the one between RP and GoodOP.
    ReplyDelete
  2. Step 7 mentions that the RP must be vulnerable to this attack. As you say, the RP shouldn't be vulnerable, but it *may* be.

    Step 3 is always possible, as the browser (and thus the attacker) can see the association handle after the RP and OP establish it by their privat echannel, because during the checkid_setup redirect one of the user-visible parameters is the association handle.

    Shared association handles are not per-user at all, as the point of shared associations is to reuse across many logins between an RP and OP. The secret of the association need not be the same between the good and evil OPs (in fact the point is they are not) but the assoc_handle is contrived to be the same, as evilOP can be configured to target a known assoc_handle.
    ReplyDelete