Hi all,
  a Measurement Factory customer reported the following bug:

   1) A user sends a CONNECT request with valid credentials
   2) Squid checks the credentials and adds the user to the user cache
   3) The same user sends a CONNECT request with invalid credentials
   4) Squid overwrites the entry in the user cache and denies the second
CONNECT request
   5) The user sends a GET request on the first SSL connection which is
established by now
   6) Squid knows that it does not need to check the credentials on the
bumped connection but still somehow checks again whether the user is
successfully authenticated
   7) Due to the second CONNECT request the user is regarded as not
successfully authenticated
   8) Squid denies the GET request of the first SSL connection with 403
ERR_CACHE_ACCESS_DENIED

On proxies with Basic authentication and SSL bumping, this can be used
to prevent a legitimate user from making any HTTPS requests

I am attaching a patch which disables authentication for tunneled requests.
Looks important bug and patch should applied.

Looking in the authentication squid3 code I am seeing issues, related to
authentication cache.
For example
  - inside Auth::Basic::User::updateCached() we are replacing with
(maybe wrong) password  a valid cache entry. This is does not looks normal.

- For digest authentication inside Auth::Digest::Config::decode method
we are retrieving user from cache, and if we found it we are marking the
cached user  as Auth::Unchecked which means that the entry needs
checking again.
Looking in the code, in practice this is means, do not use cache, always
query again.

Am I missing something?
=== modified file 'src/auth/AclProxyAuth.cc'
--- src/auth/AclProxyAuth.cc	2013-06-05 20:21:26 +0000
+++ src/auth/AclProxyAuth.cc	2014-03-21 16:05:08 +0000
@@ -61,44 +61,47 @@
     type_ = rhs.type_;
     return *this;
 }
 
 char const *
 ACLProxyAuth::typeString() const
 {
     return type_;
 }
 
 void
 ACLProxyAuth::parse()
 {
     data->parse();
 }
 
 int
 ACLProxyAuth::match(ACLChecklist *checklist)
 {
     allow_t answer = AuthenticateAcl(checklist);
+    ACLFilledChecklist *filled = Filled(checklist);
 
     // convert to tri-state ACL match 1,0,-1
     switch (answer) {
     case ACCESS_ALLOWED:
+        if (filled->request->flags.sslBumped)
+            return 1; // AuthenticateAcl() already handled this bumped request
         // check for a match
         return matchProxyAuth(checklist);
 
     case ACCESS_DENIED:
         return 0; // non-match
 
     case ACCESS_DUNNO:
     case ACCESS_AUTH_REQUIRED:
     default:
         // If the answer is not allowed or denied (matches/not matches) and
         // async authentication is not in progress, then we are done.
         if (checklist->keepMatching())
             checklist->markFinished(answer, "AuthenticateAcl exception");
         return -1; // other
     }
 }
 
 wordlist *
 ACLProxyAuth::dump() const
 {

Reply via email to