Managing TLS (SSL)

181 views
Skip to first unread message

Fred Condo

unread,
Jan 21, 2010, 12:51:54 PM1/21/10
to silverst...@googlegroups.com
I wish there were documentation on best practices for managing
SSL/TLS, in particular:
- managing the transition between http and https and back
- what pages/URLs should be behind https
- what pages/URLs do not gain a security benefit from https

Yes, I know about Director::forceSSL() -- but there is no converse
method for resuming non-SSL communication.

I'd be glad to start documenting this, but would like to hear from the
core SilverStripe team first about best practices.

--
Fred Condo, Ph.D. <fco...@quinn.com> +1(415)349-5579 Skype:fredcondo
Chief Engineer, Quinn Interactive, Inc. http://quinn.com
Web design and development since 1994.

Matt Bower

unread,
Jan 21, 2010, 7:44:17 PM1/21/10
to silverst...@googlegroups.com
It seems one could write a rule in .htaccess that prevents any request with "sapphire" in the URL from being displayed or it throws a Forbidden. However, I don't know if there are files in the sapphire folder that would ever get referenced directly through a URL (images, CSS, JS, etc)

> --
> You received this message because you are subscribed to the Google Groups "SilverStripe Development" group.
> To post to this group, send email to silverst...@googlegroups.com.
> To unsubscribe from this group, send email to silverstripe-d...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/silverstripe-dev?hl=en.
>
>

Nicolaas Thiemen Francken - Sunny Side Up

unread,
Jan 21, 2010, 8:10:01 PM1/21/10
to silverst...@googlegroups.com
I think a good way is just to put your whole site in https so you will
never have any confusion, a person never ends up on a page in the
wrong mode, you avoid most of the annoying browser messages, and you
will not have the same page available in both https and http (which
may confuse google).

Hope that makes sense.

Nicolaas

Michael Mitchell

unread,
Jan 21, 2010, 8:39:55 PM1/21/10
to silverst...@googlegroups.com
I came across this problem while working on an e-commerce site a month or two back, these were my main concerns.

Having the entire site in SSL like Nicolaas suggests whilst simple is not the best of ideas as the overhead created by serving up every single request via SSL is exponentially more than standard HTTP making it very inefficient and causing much higher server loads.

Also, a good practice with secure pages is to use a seperate subdomain that lets user know there transactions are being protected more obviously.

eg. http://www.mysite.com
     https://secure.mysite.com

I came up with a couple of lines of code which sit in Page_Controller and allow for setting of a non secure domain and a secure domain the URL Segments that require secure access, as the user browses to a secure URL Segment the Page_Controller redirects the user to the secure domain with SSL in a similar way to Director::forceSSL().

eg....

public static $domain = 'mysite.com';

public static $secure_domain = 'secure.mysite.com';

public static $secure_url_segments = array(
   'Security',
   'admin',
   'checkout',
   'account'
)

The result being a seamless transition in and out of SSL as needed.

I'm happy to share what I have or even package it into a small module.

Regards, Michael Mitchell

Phone: 03 453 4091
Mobile: 021 280 4589
Skype: michaelmitchell.co.nz
PO Box 13035 - Green Island - Dunedin


Nicolaas Thiemen Francken - Sunny Side Up

unread,
Jan 21, 2010, 9:58:38 PM1/21/10
to silverst...@googlegroups.com
Hi Michael

From the research I did, it appears that the server load is not
actually increased that much by running a site in https. Well, what
people said is that if you have a site that has a high server load
already (i.e. using a CMS will have high serverloads and static site
will have less) than the extra waiting time / load on the server from
running secure is small.

I would welcome information to the contrary as it would be good to know.

Cheers

Nicolaas

Michael Mitchell

unread,
Jan 22, 2010, 4:19:23 AM1/22/10
to silverst...@googlegroups.com
I totally agree Nicolaas,

Like you say, servers that are heavy on dynamic content tend to be impacted less by HTTPS because the time spent encrypting (SSL-overhead) is insignificant compared to content generation time.

From my understanding the overhead is NOT due to the encryption as on a modern CPU, the encryption required by SSL is trivial. Instead the overhead is due to the SSL handshakes, which are lengthy and drastically increase the number of round-trips required for a HTTPS session over a HTTP one leading to increased latency.

Generally HTTPS content will not be cached in a shared cache. Many browsers (if not all?) cache HTTPS content for the current session only (for security reasons). The impact the non-caching or less caching means clients will retrieve the same content more frequently. This results in more requests and bandwidth to service the same number of users.

Now you could say the difference in extra waiting time is "small" or "marginal" but from my experience and recent profiling of an ecommerce site showed me it can most definitely increase page load times by over a second which can be the make or break for someone deciding to stay or go.

My biggest consideration in changing to the hybrid http/https system was the extra load times of landing pages caused by non-caching (an extra 4-6 seconds at times). I recently did some analysis of google analytics stats for an ecommerce site which suggests that a quick snappy load on landing pages makes a note worthy difference on bounce rate (which is very important when you are paying a bunch for google advertising).

Hope you find some of that helpful.


Regards, Michael Mitchell

Phone: 03 453 4091
Mobile: 021 280 4589
Skype: michaelmitchell.co.nz
PO Box 13035 - Green Island - Dunedin



Nicolaas

Nicolaas Thiemen Francken - Sunny Side Up

unread,
Jan 22, 2010, 9:54:12 AM1/22/10
to silverst...@googlegroups.com
Hi Michael

That is an outstanding contribution. I think you are spot on.
Especially the caching is something to worry about. Thanks for sharing
your thoughts. I was aware of most of it, but it is great to hear
about your personal experience in this regard. I am actually
rethinking some of my own strategies.

Cheers

Nicolaas
PS - I have written a module that allows you to pre-compile parts of a
page (e.g. a large menu) so that pages load quicker:
http://sunny.svnrepository.com/svn/sunny-side-up-general/menucache.

Fred Condo

unread,
Jan 26, 2010, 12:11:25 PM1/26/10
to silverst...@googlegroups.com

We've taken a similar approach, but without using a separate domain.
From _config.php:

define( 'QI_SECURE_ADMIN_REGEX', '{^/(?:Security|admin|dev|news/post)}' );
if ( Director::isLive() ) { # Use https for secure areas in production
if ( preg_match( QI_SECURE_ADMIN_REGEX, $_SERVER['REQUEST_URI'] ) ) {
Director::forceSSL();
}
}
else { # and always on the demo server
(forceSSL is a no-op on dev).
Director::forceSSL();
}


From class Page:

static $db = array(
'SidebarContent' => 'HTMLText',
'SecurePage' => 'Boolean',
'MetaDescription' => 'Text',
);


From class Page_Controller:

/**
* Converse of Director::forceSSL.
* Redirects to plain http if the page is not secure but we have
just followed a secure link from a secure page
* to this insecure one. Works only in Live mode. No-op otherwise.
*
*/
function force_HTTP_if_live() {
if ( Director::isLive() && !preg_match( QI_SECURE_ADMIN_REGEX,
$_SERVER['REQUEST_URI'] ) ) {
$page_url = Director::absoluteURL( $_SERVER['REQUEST_URI'] );
$https_regex = '{^https:}';
if ( !$this->SecurePage && preg_match( $https_regex, $page_url ) ) {
$new_url = preg_replace( $https_regex, 'http:', $page_url );
Director::redirect($new_url);
}
}
}

function init() {
parent::init();
if ( $this->SecurePage ) {
Director::forceSSL();
}
else {
$this->force_HTTP_if_live();
}
// ...
}

Via the SecurePage field, CMS editors can check a box to force HTTPS
on any page in the site, even if it does not match the regex. We use
this for customer response forms, for example.

--
Fred

Michael Mitchell

unread,
Jan 26, 2010, 3:46:05 PM1/26/10
to silverst...@googlegroups.com
That is a very cool Idea Fred,

Good effort :D

Regards, Mike

Nicolaas Thiemen Francken - Sunny Side Up

unread,
Jan 27, 2010, 12:18:50 AM1/27/10
to silverst...@googlegroups.com
hey Everyone

When switching between http and https did you have any issues with
loosing cookies? I dont think this should happen, but we did have
this issue on one server where it we ended up switching between
https://mysite.com and http://www.mysite.com.

Cheers

Nicolaas

Nicolaas Thiemen Francken - Sunny Side Up

unread,
Jan 27, 2010, 12:21:11 AM1/27/10
to silverst...@googlegroups.com
also, it would probably be a nice idea to have another static function
in Director (sister/brother of forceSSL):

forceNonSSL

Michael Mitchell

unread,
Jan 27, 2010, 12:32:27 AM1/27/10
to silverst...@googlegroups.com
Hey Nicolaas,

I came across this problem while implementing the SSL change to secure.mysite.com from mysite.com.

The problem is to do with the cookie path of Sessions rather than SSL, the main problem being SilverStripe only sets the cookie path on the domain it is visited on, this causes cookies stored on www.mysite.com to not be available on *.mysite.com.

Unfortunately there is no simple solution to change the cookie path in SilverStripe in the current Session class.

My solution was to add functionality to Session by implementing Session::set_cookie_path().

Of course this means modifying the Sapphire Core which is not ideal.


Regards, Michael Mitchell

Phone: 03 453 4091
Mobile: 021 280 4589
Skype: michaelmitchell.co.nz
PO Box 13035 - Green Island - Dunedin


Message has been deleted

Nicolaas Thiemen Francken - Sunny Side Up

unread,
Jan 27, 2010, 12:45:29 AM1/27/10
to silverst...@googlegroups.com
stealing all of these cool ideas, I have worked it out like this:

Page_Controller:

public function init() {
parent::init();
$this->secureOrNotSecure();
}

function secureOrNotSecure() {
if(Director::isLive()) {
if ( !$this->SecurePage() ) {


$page_url = Director::absoluteURL( $_SERVER['REQUEST_URI'] );
$https_regex = '{^https:}';
if ( !$this->SecurePage && preg_match( $https_regex, $page_url ) ) {
$new_url = preg_replace( $https_regex, 'http:', $page_url );
Director::redirect($new_url);
}
}

else {
Director::forceSSL();
}
}
}

function SecurePage() {
if(
"Security" == Director::URLParam("URLSegment") || // special case for login
"AccountPage" == $this->ClassName // we put this here, as we can
not edit the AccountPage class itself
"UserDefinedForm" == $this->ClassName // we put this here, as we
can not edit the AccountPage class itself

//any othe crazy rules go here

) {
return true;
}
else {
return false;
}
}


for some page types (e.g. MyExtendedCheckoutPage) we then override
this function SecurePage. I am not saying this is any better then the
solution previously posted (worse in some ways), it is just another
way to look at it that might be of benefit to some silverstripers out
there. Going by class rather than URL segment makes it less likely the
client will break the security setup (by changing the URL of a page).

Cheers

Nicolaas

dalesaurus

unread,
Jan 27, 2010, 3:46:22 PM1/27/10
to SilverStripe Development
Here is how I solved my issue of wanting to selectively use SSL for
only specific actions or controllers, via a static var:

http://snipplr.com/view/27191/silverstripe-ssl-switching-by-statics/

This approach is a 'Only use SSL when you need it, and get requests
out of it when its not' thinking. I like using statics to set them,
but I'm sure there are many ways to carry this out. It would probably
have a better home in ContentController and a means to force all
actions to SSL.

I don't use forceSSL() because it doesn't work in Dev mode:
http://open.silverstripe.org/ticket/4509

I also had a ticket with much sloppier code I logged a while ago on
this matter:
http://open.silverstripe.org/ticket/4517

On Jan 26, 11:45 pm, Nicolaas Thiemen Francken - Sunny Side Up

Reply all
Reply to author
Forward
0 new messages