0

Just moved servers, and existing code is now showing a strange issue.

The point of the code is to catch a 'secure' blackhole error, and redirect it to the secure version of that page. It was doing it on the old server, but is now acting strange.

// App Controller

public function beforeFilter() {
    $this->Security->blackHoleCallback = 'blackhole';
}

public function blackhole($type) {
    switch($type) {
        case 'secure':
            debug(Router::url($this->here, true));
            exit;
            $this->redirect('https://' . env('SERVER_NAME') . $this->here);
            break;
    }
}

The debug shows: `http://www.example.com/'

But my browser shows 'https://www.example.com/' (notice the S)

Dave
  • 28,833
  • 23
  • 113
  • 183
  • *"The point of the code is to catch a 'secure' blackhole error..."* - forgive my ignorance... What is a secure blackhole error? – jww Aug 26 '14 at 19:03
  • @jww - it means somewhere I told my app that I wanted to require this page to be 'secure' (ie https), but it's not recognizing it as such. It's a CakePHP thing. – Dave Aug 26 '14 at 19:10

3 Answers3

2

The better answer is to not use this functionality at all.

You shouldn't be redirecting to HTTPS in your code. You should be using Strict-Transport-Security. This still involves a redirect, but it also involves setting an additional header.

You can use the features of mod_ssl:

SSLOptions +StrictRequire
SSLRequireSSL

Note that the SSLRequireSSL directive will deny all requests that do not have SSL enabled.

And a normal redirect:

RewriteCond %{HTTPS} !=on
RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [R,L]

Which basically rewrites the request to use HTTPS as a 403 redirect.

You also want to set the Strict-Transport-Security header:

Header set Strict-Transport-Security "max-age=8640000;includeSubdomains"

And done. No need to work with Cake. Handle it at the server level, since that's the server level. Which means no bad requests can even get in...

ircmaxell
  • 163,128
  • 34
  • 264
  • 314
  • The problem with this is that I don't always want to force SSL. The great part about using Cake is that I can specify which page(s) should or shouldn't require SSL. Another alternate (i suppose?) is to just throw a "requires SSL" type error page instead of redirecting. Or maybe there's a way to redirect with Cake that also sets the headers you're speaking of? – Dave Aug 26 '14 at 20:39
  • 1
    Why don't you always want to force SSL? What situation would you want a page to be non-ssl? Doing so can expose other security risks, as session tokens or other information can be leaked if it's transmitted insecurely. And non-ssl allows MITM attacks (man in the middle). And if you don't force all traffic through SSL, then attacks are possible where the communication between the MITM user and the server are secure, but the client is insecure since they are talking to the MITM. So just use SSL for everything and be done with it :-) – ircmaxell Aug 26 '14 at 20:45
  • Valid point - I guess there isn't a reason not to just use all SSL. Alright - you win :) – Dave Aug 26 '14 at 22:24
  • *"The problem with this is that I don't always want to force SSL"* - just a restatement of ircmaxell's comment... Having SSL/TLS on some pages subjects all pages to [stripping attacks](http://www.google.com/search?q=ssl+stripping+attack), where HTTPS is forced to HTTP by an attacker with a privileged network position. And its not to be confused with [downgrade attacks](http://www.google.com/search?q=ssl+downgrade+attack), which are a different attack when using SSL/TLS. But you have to be cognizant of both attacks. – jww Aug 27 '14 at 04:35
  • "No need to work with Cake" unfortunately, that's not quite true. Adding `Header set Strict-Transport-Security "max-age=8640000;includeSubdomains"` to Apache makes no difference because it doesn't set any headers for PHP scripts, it hands off the entire response to PHP. So you do need to set that header in your application. – spikyjt Aug 31 '16 at 11:30
0

I found the answer here in a similar question here: How can I securely detect SSL in CakePHP behind an nginx reverse proxy?

Add a request detector:

//AppController::beforeFilter
public function beforeFilter() {
    $this->request->addDetector('ssl', array(
        'env' => 'HTTP_X_FORWARDED_PROTO',
        'value' => 'https'
    ));
}

My app now correctly detects HTTPS as such.

Community
  • 1
  • 1
Dave
  • 28,833
  • 23
  • 113
  • 183
  • Please only do that if you **know for a fact** that you have a proxy. Otherwise you could be opening a vulnerability for a MITM where an attacker sets that header. Then you think the communication is SSL, so you allow the connection to continue. But it's plain text, allowing the attacker to read everything sent. – ircmaxell Aug 26 '14 at 20:14
  • Note: This works, but ircmaxell brings up some good points and has an alternate/likely-better solution. – Dave Aug 26 '14 at 22:35
-1
public function beforeFilter() {
  $this->Security->blackHoleCallback = 'blackhole';
  $this->Security->requireSecure();
}
FMQB
  • 653
  • 5
  • 12
  • It will require SSL enabling all the time. – FMQB Aug 26 '14 at 19:22
  • it already IS requiring it, or it wouldn't hit the 'secure' error in the first place – Dave Aug 26 '14 at 19:25
  • ‘secure’ Indicates an SSL method restriction failure. So it fails to get https and your secure type is caught. When you debug print, it shows the http scheme and you have redirected to https. so the browser URL is showing https scheme. – FMQB Aug 26 '14 at 19:34