Securing a WordPress page with https
Dec 07
What I needed
I needed a way to secure a single page. This could be an order page or a page where I want to protect user information. The problem is, even if you simply try to go to “https://mysite.com/page”, you’ll be re-directed to the http page by WordPress. Furthermore, even if you use htaccess to force the content over https, you’ll still get “partially encrypted” errors.
What is out there
There was Admin SSL, which has a 4-star rating… but did not work for me; I think the developer stopped working on it and newer versions of WP don’t work with the plugin. I also tried HTTPS for WordPress, and that didn’t work either.
Because I couldn’t find anything… I put together this hack. I guess I could make it into a plugin, but I’m lazy.
How to do it
Required knowledge/tools:
- Installation of CURL on your server
- Basic knowledge of .htaccess, and how to edit the file
- Basic php knowledge
- A working SSL certificate
1. Modify your .htaccess file
Figure out what page you wan to secure. For example, you might want to secure /contact-us. Add the following lines to your .htacccess file, before the normal wordpress lines:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^contact-us/ /secure-page.php [QSA,L]
RewriteRule ^contact-us /secure-page.php [QSA,L]
</IfModule>
# normal WordPress stuff:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
Here we’re checking to see if the visitor is requesting the “contact-us” page, and if so, we’re rewriting the request to a file called secure-page.php, instead of loading WordPress (step 2).
2. Rename /contact-us & modify menu

Next, you’ll need to get rid of the old /contact-us page you had, and rename it to contact-page-content – you can do this using WordPress… edit the Premalink, and set it to /contact-page-content.
You’ll need to exclude the page from your navigation, and then put an absolute link to /contact-us in your menu. I suggest the “Exclude Pages” plugin, found at http://wordpress.org/extend/plugins/exclude-pages/
2. Create secure-page.php
Create a file called secure-page.php and add it to your base directory (in the same location as your .htaccess file):
$domain = "www.mydomain.com"; if ( $_SERVER['HTTPS'] != 'on' ) { $url="https://$domain".$_SERVER['REQUEST_URI']; header("Location:$url"); exit; } $curl_handle=curl_init(); curl_setopt($curl_handle,CURLOPT_URL,"http://$domain/contact-page-content"); // assuming pretty urls are setup this way... curl_setopt($curl_handle,CURLOPT_CONNECTTIMEOUT,2); curl_setopt($curl_handle,CURLOPT_RETURNTRANSFER,1); $buffer = curl_exec($curl_handle); curl_close($curl_handle); if (empty($buffer)) { print "Timed Out"; } else { $buffer = str_replace("src=\"http://$domain", 'src="', $buffer); $buffer = str_replace("src='$domain", "src='", $buffer); $buffer = str_replace("url(\"http://$domain", 'url("', $buffer); $buffer = preg_replace ("/http:\/\/.*?(\/.*?\.css)/", "$1", $buffer); $buffer = preg_replace ("/http:\/\/.*?(\/.*?\.js)/", "$1", $buffer); $buffer = preg_replace ("/http:\/\/.*?(\/.*?\.xml)/", "$1", $buffer); print $buffer; }
OK, here’s an explanation:
You renamed /contact-us to /contact-page-content, and then excluded it from your navigation. Note that the page still exists – you can enter /contact-page-content into your browser, and it will show the page, right? But, you hid it from navigation, and you provided the user with a link to /contact-us. Some people might say this solution is still not “secure”, but I could honestly care less if the user can still go to /contact-page-content… if they do, who cares?
As for what secure-page.php is doing:
The first part checks to make sure the page is served over https. If not, it forwards to the https version, and exits.
Next, we use CURL to request another page (contact-page-content). Remember that you can still navigate to /contact-page-content, and CURL is doing just that. CURL then downloads the entire content of the page into a buffer/string.
Next, we replace all references to http assets to https… or just “/”. We do this because WordPress uses absolute URLs to assets (”http://mysite.com/image.jpg”), and we want it to be relative (”/image.jpg”). We then echo out the buffer, and voila, your page is now secured.
Conclusion
I should turn this into a plugin, but I’m lazy and I just don’t have the time…
If you have problems just comment on this post and I’ll get back to you!




New blog theme looks good!
How would this work to secure multiple pages? Say, three.
Good question!
To secure three pages… you’d just modify your .htaccess file:
RewriteRule ^page-one/ /secure-page.php [QSA,L]
RewriteRule ^page-one /secure-page.php [QSA,L]
RewriteRule ^page-two/ /secure-page.php [QSA,L]
RewriteRule ^page-two/secure-page.php [QSA,L]
RewriteRule ^page-three/ /secure-page.php [QSA,L]
RewriteRule ^page-three/secure-page.php [QSA,L]
Then, in secure-page.php, you’d handle those requests:
add this to line 0:
$requested_page = $_SERVER['REQUEST_URI'];
switch ($requested_page)
{
case “/page-one”: $pagetoload = “page-one-content”;
break;
case “/page-two”: $pagetoload = “page-two-content”;
break;
case “/page-three”: $pagetoload = “mypagethree”;
break;
}
// where, the right side of $pagetoload = X… X = the page you renamed/hid in wordpress
Next, you’d modify the page that CURL loads:
from line 5:
exit;
}
$curl_handle=curl_init();
curl_setopt($curl_handle,CURLOPT_URL,”http://$domain/$pagetoload”); // assuming pretty urls are setup this way…
curl_setopt($curl_handle,CURLOPT_CONNECTTIMEOUT,2);
curl_setopt($curl_handle,CURLOPT_RETURNTRANSFER,1);
$buffer = curl_exec($curl_handle);
curl_close($curl_handle);
if (empty($buffer))
Hope this helps… ping me back if you have questions
Also… I’m thinking about making a plugin… but I’m pretty busy right now. Maybe if there’s enough interest it would be fun to make a plugin…
This is incredible. I’ve been searching for a solution for this for over a week. I’m stunned that this hasn’t made it into the core wordpress release yet as people have been selling on their sites since wordpress began. DO THE PLUGIN!!! There’s absolutely nobody else doing this feature right now (the other two plugins are no longer supported). It would make for great free marketing for your services and website!
haha… I’m thinking about it, but honestly I have so much work right now that I don’t think I have the time!
Did you get the solution to work for you?
sadly, no. i can see how it would work but something is broken in my code. ill keep at it. i’m sure i’ll figure it out. i’ve also been looking at a software called digital access pass that looks like it might do what i need. thanks for posting this.
Ok – any specific errors?
You’re running a linux server right?
Let me know about any specifics and I’d be happy to take a look at it.
So I was just reading this, and I had an idea for multiple pages without having to rewrite the page every time.
What if we added this code:
[code]
$URI = $_SERVER['REQUEST_URI']; //put the URI into a new variable
if($URI[strlen($URI)-1] == "/") //check to see if there's a slash on the end of the requested URI, as this could mess things up later on
{
substr_replace($URI, "", -1); //kill the slash
}
[/code]
…and then replaced what was line 5 with:
[code]
curl_setopt($curl_handle,CURLOPT_URL,"http://".$domain.$URI."-content");
[/code]
(This of course assumes you’ve used the “-content” naming convention…)
It seems like it should work, and it saves all the trouble of adding an extra line for each page (which could get quite tedious).
Yes! You can 100% do that. For the sake of this example I wanted to keep it easy for newbies.
Good idea!
Alex
Hi again! My code as it was didn’t work (I can give you the working code if you want…), but I did get it to work with some tweaking.
Anyways. After following your tutorial (with a few minor tweaks), I still get the error that some parts of the page aren’t secure – any idea why this is, and/or how to fix it?
Thanks!
~Sonic
Hello, I am having trouble getting this to work but I am glad you have put this out there, it is much needed functionality in Wordpress.
Are you getting any specific errors?
Are you getting any specific errors… what happens when you try it?
Any idea if there’s a way to secure a page with a shared SSL cert? This is the closest I’ve come to some sort of WordPress SSL solution. Thanks for posting this.
This should work with shared SSL – I actually have a live working version at https://www.mytowntutors.com/tutor-application (or so I think!)
This is using a GoDaddy Shared SSL certificate.
Whose your hosting/ssl provider?
Alex
So. I’m looking into developing a secure client portal for a wp customer of mine. Would it be possible to secure the whole site with ssl, including login, admin, etc…?
How secure is this solution? Does it have 64-bit encryption?
Thanks,
Bob
This solution does not secure /wp-admin or anything.
It simply secures individual pages (e.g. checkout pages).
The level of encryption depends on the certificate you have. Most SSL certs are a minimum of 128-bit encryption. For example, GoDaddy’s cheapest “shared” certificate is around $20 a year: http://www.godaddy.com/gdshop/ssl/ssl.asp?ci=8979
Alex
thanks for your answer Alex. so if i want to secure the login page for customers to login, this solution wouldn’t work?
any ideas as to how this can be done?
and i’m assuming that i need a private ssl certificate not a shared one?
thanks,
Bob
It could be possible – I honestly haven’t tested it yet though!
You need an SSL certificate that can be installed on your domain. GoDaddy calls these “shared” ssl certificates. They’re pretty cheap. It will work on a shared certificate – I have it working on a site right now.
I wish I had some time right now – I am betting it would work for /wp-admin, I just can’t test it today
@admin: I tried to apply your tips for Wordpress MU 2.9.1. But fortunately modifying only .htaccess file worked for me. To secure http://www.domain.com/pricing-signup page i added following to .htaccess file as you suggested before the normal wordpress lines:
RewriteEngine On
RewriteBase /
RewriteCond %{SERVER_PORT} 80
RewriteCond %{REQUEST_URI} pricing-signup
RewriteRule ^(.*)$ https://%{SERVER_NAME}/$1 [R,L]
I am not sure of any consequences that might cause but it works.
oh wow… so that was the only modification you had to make?
If so, my entire solution is overkill!
Ah, never mind, i was mistaken. I thought it’s done when i saw https in the address bar of firefox. Some js and css files are loaded via http, so i still need to leverage secure-page.php.
Sorry for confusion and thanks for sharing the trick.
Hi Admin,
I think I was just getting a 404 error, I do not remember 100% now. I ended up basically turning ssl on the whole website, but that is causing a few problems of its own. I would rather have the ssl just run on the shopping cart and checkout pages. The site is countryontheriver.com, please feel free to reply if you have any insight. Thanks again!
hi admin,
great resource and thanks for putting this up. i’m trying to implement it now for the ‘wp-admin’ page when logging in, but not sure what to use as its name when inputting to the .htaccess file and secure-page.php file. Any help is greatly appreciated, thanks!
pf
This solution works fine for getting the user to your https: page, but there’s still a nagging issue when the user leaves the page by clicking a menu item or back arrow — namely the browser now stays in https: mode when calling the next page so IE pops up an error saying that new page is not secure. Bummer.
Does anyone have an easy way to set .htaccess to make all pages other than the secure page always redirect to http: not https:?
FYI, when I implemented this solution I had problems with the last three lines of secure-page.php. When included as shown the browser would print an empty page. In my case my fix was to delete those lines and replace them with:
$buffer = str_replace(’http:’, ‘https:’, $buffer);
to replace all instances of http with https in the secure page.
Thanks Jonathan!
That’s strange. I think that may have to do with your solution/change that you made. On my pages it leaves the links at https. I wonder?
Hi
I have spent hours looking for a solution and am ready to trash wpecommerce and use oscommerce for my cart!
I tried your and it makessense but I cannot get it to work.
First, why do I have to change the name of the contact page? Can’t I simply use a checkout page?
And here my error. This prints to the browser rather than the page:
$domain = “www.totalguitar.net”; if ( $_SERVER['HTTPS'] != ‘on’ ) { $url=”https://$domain”.$_SERVER['REQUEST_URI']; header(”Location:$url”); exit; } etc….
Thanks
Hi Deb,
That’s strange! Yes, I used the contact page just for example purposes only. I think you have some kind of PHP configuration issue… it should not be outputting any PHP code. Are you sure the above isn’t somehow in quotes? Do you mind emailing me your exact PHP script? I’d be happy to look at it – my email is cook at propellingsolutions.com.
FIxed the php page – stupid mistake. What causes timed out to print? I got that far this time.
Thx
I’m getting the “timed out” error as well.
Make sure the page can be read without being logged in. The PHP script is trying to navigate to the page – if it’s password protected or you’re using a plugin like members-only, then it won’t work. What’s the requested page URL?
Can’t you just use the .htaccess changes or the code above that redirects the page to https:// and then use a page template which only includes a simple header that matches your theme and do whatever processing from there?
Or I guess use a page template to remove a lot of the https:// navigation to prevent that issue?
Yep! You can do that. Either way works – this solution allows you to keep your entire site in tact. Sometimes small plugins like weather widgets need to be removed, but overall this is a semi-automatic way of doing it.
I’m still uncomfortable with the non-ssl page being available. Seems like the solution there is to just check if it’s that page and redirect to the ssl page. Then, it solves that issue. Plus, if somehow they get by that, on that page you just put a check to make sure it’s SSL before you display anything, no?
Hey, gang, I’m still unable to find a good solution to this problem: Alex’s code sets all the links in the secured page to https: but the bad news is that means if you user clicks any link on your now secure page, like the navigation menu or a button, WordPress tries to call that new page with https: not http:. Of course, IE is going to popup an error that you are trying to go with https: to a page that isn’t secure.
I thought the answer was to write in my .htaccess file a command to change any calls to https: to any page other than the one that Alex’s code is securing to switch from https: back to http:
For instance, if the page Alex’s code is securing is /apply then in .htaccess I can say if you are calling https: on port 443 and your URL doesn’t include “apply” then call with http:
RewriteCond %{SERVER_PORT} ^443$
RewriteCond %{REQUEST_URI} ^.*\.*$
RewriteRule !^(apply)(.*)$ http://%{SERVER_NAME}%{REQUEST_URI} [L,R]
However, while this .htaccess code works fine when run by itself (it will switch any https: call back http:) whenever I install it then it causes Alex’s code to fail.
I’ve spent countless hours trying to debug this, no luck so far.
Alex’s solution would be perfect IF it not only secure one page by making all URLs in that page https: but also was smart enought if a user clicked one of those https: links to go back to using http: to get that page insecure page.
If I ever find the answer I’ll post here.
I got this working well. I took the approach I mentioned in my above comment. I created a specific page template for the page that I wanted to secure.
One other note, is in my specific page template, I had to have custom header and footer pages. This works those for custom header and footers:
get_footer(sslpage);
get_header(sslpage);
That will include footer-sslpage.php and header-sslpage.php
Then, in the page template I only included HTTPS links. Yes, this did mean removing much of my navigation. I might work later to try and include some minimal navigation that we’ll redirect a HTTPS page to the main page or something.
However, I don’t necessarily want them distracted by other links. I want them taking the secure action (ie. paying me money).
Hey, not to steal your thunder or anything, but I’ve created a plugin to fix the partially encrypted errors for any Wordpress page being accessed over HTTPS.
Ladies and gentlemen, Wordpress HTTPS/.
Cool! I’m glad you did! Getting tired of this hack
Does it change ALL the links on the page to https? The problem with that is that if they navigate to any https:// page on the site, then when they click on nav links they’ll be navigating as http:// from then on.
No, my plugin only affects script, link (stylesheet), and img tags. If you want your entire site to be HTTPS, then change your WordPress Address and Blog Address to HTTPS in Settings > General in your WordPress admin panel.
I avoided adding this functionality for this reason. Also, WordPress 3.0 does this automatically. When pages are viewed over HTTPS, WordPress 3.0 automatically changes all internal links to HTTPS.
This functionality is not always desired, though. I’ve done some E-commerce sites that I only wanted to the checkout pages to be HTTPS, and have had to leave them at 2.9 so that WordPress does not change all my links when I don’t want it to.
Mvied,
That’s a good thing. I just handle mine with redirects and then page templates on the pages that I want to only have SSL.