Open Bug 698523 Opened 13 years ago Updated 2 years ago

nsHttpChannelAuthProvider::GetCredentialsForChallenge returns wrong credentials

Categories

(Core :: Networking: HTTP, defect, P5)

x86_64
Linux
defect

Tracking

()

People

(Reporter: info, Unassigned)

References

(Blocks 1 open bug)

Details

(Keywords: reproducible, Whiteboard: [necko-would-take])

User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:7.0) Gecko/20100101 Firefox/7.0
Build ID: 20110927153135

Steps to reproduce:

Trying to create multiple https connections to the same host and url with different username and passwords using xmlhttprequest.

URI = https://exchange2010.example.com/EWS/Exchange.asmx
users:
1. username = jane, domain=example, password=test1
2. username = john, domain=example, password=test2
3. username = karel, doman=example, password=test3
etc...


Actual results:

Three connections are created but the are all authenticated with the first set of credentials because the first is stored in cache and for the following this entry is used because credentials are stored in the authcache based on shema, host, port and realm. The key is the same for all connections.


Expected results:

The key for saving in cache should also contain the username or some other settable part.

I get it to work when i specify a different hostname for the same ip-address for each connection. Because the key will be different then and for each set of credentials a new key is saved. But this is not workable because normal users cannot control this.
Severity: normal → major
Keywords: reproducible
See Also: → 654348, 547871
The authentication credentials are stored in a hashtable which uses the scheme, host, port and realm as key to store the credentials. See following part in file "nsHttpChannelAuthProvider.cpp" method "nsHttpChannelAuthProvider::GetCredentialsForChallenge"

    nsHttpAuthEntry *entry = nsnull;
    authCache->GetAuthEntryForDomain(scheme.get(), host, port,
                                     realm.get(), &entry);

After this the check is done if the identity is valid. When not valid and NOT identFromURI and matching credentials from cache the specified credentials are replaced by the cached credentials.

In the case where we try to create three connections to the same server with different usernames it will always replace the specified credentials by the cached version.


    // hold reference to the auth session state (in case we clear our
    // reference to the entry).
    nsCOMPtr<nsISupports> sessionStateGrip;
    if (entry)
        sessionStateGrip = entry->mMetaData;

    // for digest auth, maybe our cached nonce value simply timed out...
    PRBool identityInvalid;
    nsISupports *sessionState = sessionStateGrip;
    rv = auth->ChallengeReceived(mAuthChannel,
                                 challenge,
                                 proxyAuth,
                                 &sessionState,
                                 &*continuationState,
                                 &identityInvalid);
    sessionStateGrip.swap(sessionState);
    if (NS_FAILED(rv)) return rv;

    LOG(("  identity invalid = %d\n", identityInvalid));

    if (identityInvalid) {
        if (entry) {
            if (ident->Equals(entry->Identity())) {
                LOG(("  clearing bad auth cache entry\n"));
                // ok, we've already tried this user identity, so clear the
                // corresponding entry from the auth cache.
                authCache->ClearAuthEntry(scheme.get(), host,
                                          port, realm.get());
                entry = nsnull;
                ident->Clear();
            }
            else if (!identFromURI ||
                     nsCRT::strcmp(ident->User(),
                                   entry->Identity().User()) == 0) {
                LOG(("  taking identity from auth cache\n"));
                // the password from the auth cache is more likely to be
                // correct than the one in the URL.  at least, we know that it
                // works with the given username.  it is possible for a server
                // to distinguish logons based on the supplied password alone,
                // but that would be quite unusual... and i don't think we need
                // to worry about such unorthodox cases.
                ident->Set(entry->Identity());
                identFromURI = PR_FALSE;
                if (entry->Creds()[0] != '\0') {
                    LOG(("    using cached credentials!\n"));
                    creds.Assign(entry->Creds());
                    return entry->AddPath(path.get());
                }
            }
        }
        else if (!identFromURI) {
            // hmm... identity invalid, but no auth entry!  the realm probably
            // changed (see bug 201986).
            ident->Clear();
        }
Status: UNCONFIRMED → NEW
Ever confirmed: true
Whiteboard: [necko-would-take]
Bulk change to priority: https://bugzilla.mozilla.org/show_bug.cgi?id=1399258
Priority: -- → P5
QA Whiteboard: qa-not-actionable

In the process of migrating remaining bugs to the new severity system, the severity for this bug cannot be automatically determined. Please retriage this bug using the new severity system.

Severity: major → --
Blocks: necko-auth
Severity: -- → S3
You need to log in before you can comment on or make changes to this bug.