Page MenuHomePhabricator

$wgServer with initial https:// does not force HTTPS (wgSecureLogin)
Closed, ResolvedPublic


On a vanilla MediaWiki 1.29alpha (90f0807) with no extension, when $wgServer has an initial "https://" (instead of "http://" or "//"), I would have expected that it would force MediaWiki to redirect every HTTP requests to HTTPS, and it is what is documented on, but it’s not the case for anonymous visitors and logged-in users (although the login page redirects to HTTPS during authentication, but further navigation can be done with HTTP).

When I add $wgSecureLogin = true, the login page is not redirected to HTTPS; it is normal since this setting is only activated when $wgServer is protocol-relative, but the whole feature is anyway defeated in this case.

I observed it first on a production MediaWiki 1.27 and then reproduced it on a vanilla MediaWiki 1.29alpha.

I’m not sure this bug can be qualified as a "security issue", but given I have doubts, I prefer fill it as such, instead of the contrary. Anyway it would be better to fix this bug before T118413 is done.

On T107604, @csteipp. wrote:

Instead of setting $wgSecureLogin=false on sites that are https only (e.g., T103021 for the WMF), make the option more efficient so that it can be maintained as a backup control in case http->https redirection at the pre-application layer is broken.

  • Don't show user preference to "use insecure connection" for https-only sites -
  • Force all cookies to be set secure, reguardless of user preference, on https-only sites
  • Decrease the size of the forceHTTPS=1 cookie (iirc, facebook used "_s=1" when they converted to https) to minimize overhead

Event Timeline

I began digging to try to understand what was happening.

The high-level result is in MediaWiki::main() where $request->getSession()->shouldForceHTTPS() is false instead of true, hence the page is not redirected to its HTTPS alter ego.

In the lower levels, I focused around the session management initialisation, called from the Setup.php file (in RequestContext::getMain()->getRequest()):

  • in SessionBackend::__construct() (called in SessionManager::getSessionFromInfo()) the forceHTTPS property is initialised with $info->forceHTTPS(),
  • the $info variable has its value initialised with SessionProvider->newSessionInfo() in SessionManager::getEmptySessionInternal() with the first SessionProvider (CookieSessionProvider in the default configuration)
  • SessionProvider->newSessionInfo() returns a new SessionInfo object with no configuration parameter involved,
  • SessionInfo constructor creates a new object with, in particular, its property forceHTTPS initialised to false.

I’m not sure how the things should be done, but the config parameter $wgServer should be used in the session management, during the construction of the objects.

The session stuff is unrelated. There's a preference to indicate that the user wants to always use HTTPS, which causes CookieSessionProvider to send most cookies with the 'secure' flag and to send a 'forceHTTPS' cookie unsecure so MediaWiki can redirect. All the stuff you identified in the session handling is dealing with setting and testing for that cookie.

What you probably want to look at is that MediaWiki ignores $wgSecureLogin if $wgServer isn't protocol-relative, added in rMW8102bb87bcb2: (bug 40679) Set $wgSecureLogin to false for $wgServers with schemes. with the thinking that if you configure $wgServer as https then you're saying your wiki isn't accessible over http at all (i.e. you have a generic http→https redirector in place like WMF does).

Indeed for $wgSecureLogin, but in fact it is only a side-effect, the main point is there is no redirect from HTTP to HTTPS. And indeed a generic http→https redirector is better than a MediaWiki one.

I didn’t mention it, but the user preference 'prefershttps' has the default value 1, so when $wgServer is '' all parameters say the site should be HTTPS. Perhaps the thing I assumed but MediaWiki is not [currently] assuming is: “if some HTTP is coming it should redirect to HTTPS”. In fact, this is a matter of “expected behaviour”: during a transition to HTTPS, the first thing I did is to change $wgServer and if/when things are correct, force the HTTPS at the webserver-level.

Perhaps the issue is that PROTO_CURRENT should only use the current protocol if wgServer is relative. If wgServer specifies a specific protocol, than PROTO_CURRENT should use that protocol instead of the current one.

See code in MediaWiki::tryNormaliseRedirect()

Can this be opened up to public? I understand that lack of https is a security issue - but I think its unclear if this is intended behaviour or not, and I would like feedback from the larger community.

Yes, it can be public. I hesited when I opened the bug, but given it is configuration-specific and should not be the prefered method to force https, this is only a minor security issue.

Bawolff changed the visibility from "Custom Policy" to "Public (No Login Required)".Feb 2 2017, 7:40 PM
Ottomata triaged this task as Medium priority.Mar 6 2017, 7:45 PM
Krinkle renamed this task from $wgServer with initial https:// does not force HTTPS to $wgServer with initial https:// does not force HTTPS (wgSecureLogin).Apr 28 2017, 10:16 PM
Krinkle updated the task description. (Show Details)
Krinkle added a subscriber: csteipp.

Change 134756 had a related patch set uploaded (by Krinkle; owner: CSteipp):
[mediawiki/core@master] WIP: Respect wgForceHttps on login

Change 134756 abandoned by Chad:
WIP: Respect wgForceHttps on login

Tgr claimed this task.
Tgr added a subscriber: Tgr.

We now have a $wgForceHTTPS flag for HTTPS-only wikis which forces all cookies to use the secure flag, gets rid of the forceHTTPS cookie, and forces redirects unconditionally. HTTPS-only sites should use that. I wrote some high-level documentation at Manual:HTTPS, please expand / ask if it is unclear.

That checks the boxes of @csteipp's comment quoted in the task description (although it doesn't seem related to this task anyway). What remains is making clear that $wgForceHTTPS should be set for a HTTPS-only wiki, which I now added to the $wgServer docs. I don't think much else should be done here. (In the longer term, I think there is a wish to remove protocol juggling from MediaWiki altogether and focus it on the HTTPS-only use case.) Filed T266625: MediaWiki installer should ask whether the wiki is HTTPS-only, set config accordingly as a possible follow-up.