5

i have a login form:

<form method =POST action="/login.php">
...
</form>

i would like the login.php page to redirect to using https.

i don't want to send the user to https://.../login.php because they might change the link. but i want to do a redirect on the server side before i parse the login form data and log the user in.

i found and example:

if($_SERVER["HTTPS"] != "on") {
   header("HTTP/1.1 301 Moved Permanently");
   header("Location: "https://" . $_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"]);
   exit();
}

but i don't have $_SERVER["HTTPS"] if i var_dump($_SERVER);

i do have $_SERVER['SERVER_PORT'] witch is 80.

any ideas?

Thanks

Patrioticcow
  • 26,422
  • 75
  • 217
  • 337
  • "i don't want to send the user..." "i want to do a redirect" The two are mutually incompatible. Do you want to force the user to use SSL? If so, you need to redirect (send) the user to the HTTPS version of the login form. – George Cummins Feb 03 '12 at 20:53
  • `but i don't have ` of course you will not have it when you connect with regular `HTTP`. And port 80 tells the same. `$_SERVER["HTTPS"] = 'on';` when you are connected through the HTTPS and your port in that case would be `443`. You script is doing the right thing, it check whether the current connection is HTTP and if it is not - it redirects to the HTTPS version. – Cheery Feb 03 '12 at 20:54
  • i could, but there is a possibility for the user to change the link to HTTP. I need to make a check on the login.php page for HTTPS – Patrioticcow Feb 03 '12 at 20:55
  • Then you need to employ the redirect in the login.php script. If the user changes the link to use the HTTP version, your script will simply redirect him again to the HTTPS version. – George Cummins Feb 03 '12 at 20:56
  • yes @George Cummins, what is the script? – Patrioticcow Feb 03 '12 at 20:58
  • http://httpd.apache.org/docs/2.2/mod/mod_ssl.html#sslrequiressl – j08691 Feb 03 '12 at 21:00

4 Answers4

6

If you allow them to post to /login.php over plain HTTP and then redirect to HTTPS, you defeat the purpose of using HTTPS because the login information has already been sent in plain text over the internet.

What you could do to prevent the user from changing the URL, is make it so the login page rejects the login if it is not over HTTPS.

What I use to check for the use of HTTPS is the following:

if (!isset($_SERVER['HTTPS']) || !$_SERVER['HTTPS']) {
    // request is not using SSL, redirect to https, or fail
}

If you are running your secure server on the default port of 443, then you can also check to see if that is the port, but PHP sets the $_SERVER['HTTPS'] value to non-empty if SSL is used so I would check for the presence of that for best practice.

EDIT:

If the user is so included to manually change the https to http and want to send their information over plain text, there isn't anything you can do to stop them, but if you disallow login over HTTP, so even the correct information will not log them in, you can force them to use https by making it the only thing that works.

drew010
  • 68,777
  • 11
  • 134
  • 162
  • Yes, add that check to login.php near the beginning of the script. You could do several things, from just denying the login with an error saying https is required, or using a 301 header to redirect to https. – drew010 Feb 03 '12 at 21:01
5
if($requireSSL && $_SERVER['SERVER_PORT'] != 443) {
    header("HTTP/1.1 301 Moved Permanently");
    header("Location: https://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
    exit();
}
Rayiez
  • 1,420
  • 19
  • 20
5

Whatever page you use to display your login form should already be using https:// before the form is filled out, and then it should be submitted to another https:// address. Otherwise, you'll leave the form open to attack.

You could look into mod_rewrite to automatically redirect any request using http:// to https://, at least for your login page.

WWW
  • 9,734
  • 1
  • 29
  • 33
  • As long as the form is posted to https, it does not matter if the form itself is on a non-https page. – drew010 Feb 03 '12 at 21:05
  • @drew010: http://security.stackexchange.com/questions/1692/is-posting-from-http-to-https-a-bad-practice – WWW Feb 03 '12 at 21:17
  • True the landing page's html could be modified by a man-in-the-middle, but the data will still be encrypted if it is posted to an HTTPS page. For best practice, I usually force the whole site to use SSL and not just specific pages. Following that guide, you should make your login form on https as well. – drew010 Feb 03 '12 at 21:21
3

Assuming that your page with the login form is generated by index.php, you need to put the example code for HTTP to HTTPS redirection in index.php. This will ensure that when the user fills up the form and submits it, it is submitted to /login.php via HTTPS and not HTTP.

Putting this check inside login.php is futile because by the time login.php gets the request and tries to redirect to the corresponding HTTPS URL, well, the credentials have already been submitted to it as plaintext which is what you should want to avoid.

The observation that you see $_SERVER['SERVER_PORT'] to be 80 and $_SERVER["HTTPS"] to be not set when you put the check inside login.php is a further proof of the fact that login credentials are being submitted to it via HTTP and thus the login credentials are reaching your server from the client unencrypted. This has to be avoided by following what I said in the first paragraph of this response.

BTW, I wouldn't use PHP to do this sort of redirection. Such redirections are very conveniently handled by mod_rewrite in Apache HTTPD.

An example, assuming that your login page is available at the URL, http://example.com/foo/:

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^foo/$ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
Susam Pal
  • 32,765
  • 12
  • 81
  • 103