* (bug 13905) Blacklist Mac IE from HttpOnly cookies; it eats them sometimes
authorBrion Vibber <brion@users.mediawiki.org>
Thu, 1 May 2008 20:25:17 +0000 (20:25 +0000)
committerBrion Vibber <brion@users.mediawiki.org>
Thu, 1 May 2008 20:25:17 +0000 (20:25 +0000)
God I wish this browser would finish dying. :D

The particular situation was that the session cookie was getting eaten as "disabled", thus not sent back to the server so your session state never quite happened. Other cookies on submit seemed to come in intact, but without the session cookie you'd get a big fat error message, even if you set the long-term login cookie option.

Mac/IE seems to always *see* the HttpOnly cookies, but it sometimes marks them as "disabled". It seems to be incorrectly parsing the options after the path, sometimes seeing "/;" as the path instead of "/". Failure is more likely if there's no expiration option (as with the session cookie), or if there *is* a secure option set.

Anyway, just set up a user-agent blacklist $wgHttpOnlyBlacklist and copied the Mac/IE entry over. The HttpOnly setting now gets ignored for blacklist hits as well as for old PHP versions, the check being encapsulated into wfHttpOnlySafe().

Also added some logging for cookie settings, around the setcookie() and session_set_cookie_params() calls.

RELEASE-NOTES
includes/DefaultSettings.php
includes/GlobalFunctions.php
includes/User.php

index 2bc9570..7b8b730 100644 (file)
@@ -233,6 +233,7 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
   "show hidden categories" option on
 * (bug 13915) Undefined variable $wltsfield in includes/SpecialWatchlist.php
 * (bug 13913) Special:Whatlinkshere now has correct HTML markup
+* (bug 13905) Blacklist Mac IE from HttpOnly cookies; it eats them sometimes
 
 
 === API changes in 1.13 ===
index 3605f6a..43beaf3 100644 (file)
@@ -1497,6 +1497,17 @@ $wgDisableCookieCheck = false;
  */
 $wgCookieHttpOnly = version_compare("5.2", PHP_VERSION, "<");
 
+/**
+ * If the requesting browser matches a regex in this blacklist, we won't
+ * send it cookies with HttpOnly mode, even if $wgCookieHttpOnly is on.
+ */
+$wgHttpOnlyBlacklist = array(
+       // Internet Explorer for Mac; sometimes the cookies work, sometimes
+       // they don't. It's difficult to predict, as combinations of path
+       // and expiration options affect its parsing.
+       '/^Mozilla\/4\.0 \(compatible; MSIE \d+\.\d+; Mac_PowerPC\)/',
+);
+
 /** A list of cookies that vary the cache (for use by extensions) */
 $wgCacheVaryCookies = array();
 
index 3594fe5..e86ae19 100644 (file)
@@ -2244,6 +2244,22 @@ function wfIsLocalURL( $url ) {
        return Http::isLocalURL( $url );
 }
 
+function wfHttpOnlySafe() {
+       global $wgHttpOnlyBlacklist;
+       if( !version_compare("5.2", PHP_VERSION, "<") )
+               return false;
+       
+       if( isset( $_SERVER['HTTP_USER_AGENT'] ) ) {
+               foreach( $wgHttpOnlyBlacklist as $regex ) {
+                       if( preg_match( $regex, $_SERVER['HTTP_USER_AGENT'] ) ) {
+                               return false;
+                       }
+               }
+       }
+       
+       return true;
+}
+
 /**
  * Initialise php session
  */
@@ -2256,7 +2272,15 @@ function wfSetupSession() {
                # application, it will end up failing. Try to recover.
                ini_set ( 'session.save_handler', 'files' );
        }
-       $httpOnlySafe = version_compare("5.2", PHP_VERSION, "<");
+       $httpOnlySafe = wfHttpOnlySafe();
+       wfDebugLog( 'cookie',
+               'session_set_cookie_params: "' . implode( '", "',
+                       array(
+                               0,
+                               $wgCookiePath,
+                               $wgCookieDomain,
+                               $wgCookieSecure,
+                               $httpOnlySafe && $wgCookieHttpOnly ) ) . '"' );
        if( $httpOnlySafe && $wgCookieHttpOnly ) {
                session_set_cookie_params( 0, $wgCookiePath, $wgCookieDomain, $wgCookieSecure, $wgCookieHttpOnly );
        } else {
index 3e01e28..9cbad66 100644 (file)
@@ -2006,8 +2006,17 @@ class User {
                if( $exp == 0 ) {
                        $exp = time() + $wgCookieExpiration;
                }
-               $httpOnlySafe = version_compare("5.2", PHP_VERSION, "<");
-               
+               $httpOnlySafe = wfHttpOnlySafe();
+               wfDebugLog( 'cookie',
+                       'setcookie: "' . implode( '", "',
+                               array(
+                                       $wgCookiePrefix . $name,
+                                       $value,
+                                       $exp,
+                                       '/',
+                                       $wgCookieDomain,
+                                       $wgCookieSecure,
+                                       $httpOnlySafe && $wgCookieHttpOnly ) ) . '"' );
                if( $httpOnlySafe && isset( $wgCookieHttpOnly ) ) {
                        setcookie( $wgCookiePrefix . $name,
                                $value,