SSL Redirect to NON-SSL

I have only 2 URL that need SSL rest of the website is non-ssl

however the urls dynamic using mod_rewrite

with the following

RewriteRule ^/?([a-zA-z_]+).html$ page.php?pg=$1

the urls would
domain.com/register.html
domain.com/checkout.html

everytime i would try to for SSL on those pages it’ll redirect the url to page.php?pg=register

This is what i’m using

RewriteCond   %{SERVER_PORT}  ^443$
RewriteCond   %{REQUEST_URI}  !^/register.html$
RewriteCond   %{REQUEST_URI}  !^/checkout.html$
#RewriteRule ^(.*) http://www.localsalons.com/$1 [L,R]

I was thinking i can do the HTTPS 301 Redirect with PHP… but i still need HTACCESS to make sure the rest of the site stays http :\

Probably your SSL-related rewrite is listed after your page.php rewrite. So by the time the SSL-related rewrite kicks in, the internal URL has already been rewritten to page.php. Try putting the SSL-related redirect first.

If you still have problems after that, trying showing your whole htaccess file.

Shaydez,

Two points:

  1. I’m quite sure that both register and checkout are using support files (images, css, js, etc) so forcing non-SSL on the support files will cause the browsers to report your page as insecure (mixed security, actually). You DON’T want that so be sure that only your page scripts get the redirections, not every file as you’ve shown.

  2. Even with mod_rewrite redirections, I still rely on embedded PHP to check the SSL status and redirect (if necessary) because you just can’t be too careful when dealing with huge liability issues (visitor/client cc data).

Regards,

DK

Yeah the SSL is before the page rewrite… I have tried putting it after the page rewrite… just to see what happens…




#ErrorDocument 404 /404.php

RewriteEngine On
	RewriteCond %{HTTP_HOST} ^domain\\.com
	RewriteRule (.*) http://www.domain.com/$1 [R=301,L]
	RewriteRule index.php http://www.domain.com/$1 [R=301,L]


####-- Secure Socket Rewrite Conditions. ####
# Allow some URIs to be https if requested
RewriteCond   %{SERVER_PORT}  ^443$
RewriteCond   %{REQUEST_URI}  !^/register.html$
RewriteCond   %{REQUEST_URI}  !^/checkout.html$
RewriteCond   %{REQUEST_URI}  !^/(.*).css$ 
RewriteCond   %{REQUEST_URI}  !^/(.*).png$
RewriteCond   %{REQUEST_URI}  !^/(.*).jpg$
RewriteCond   %{REQUEST_URI}  !^/(.*).js$
RewriteRule ^(.*) http://www.domain.com/$1 [L,R]
####-- Secure Socket Rewrite Conditions. ####

#excludes directory from my rewrite rules
RewriteRule ^(admin|library|images|lab|blog|mailer|apps|media|phpmailer|partners|account|lib)($|/) - [L]

RewriteRule (.*)/(.*)-(.*)/(.*)\\.html$ details.php?name=$2&storeID=$3&cmspage=$4
RewriteRule (.*)/(.*)-(.*)\\.html$ details.php?name=$2&storeID=$3

#Regular Content Pages from CMS
RewriteRule ^/?([a-zA-z0-9_]+).html$ page.php?pg=$1


As for Partial Security… I have the rewrite condition checking all the images, js, css files and forcing them to be https. its kind of redundant since they’re all relative linking. so i don’t mind removing that section.

Shay,

I would have gone about it the opposite way:

  1. Deal only with scripts, i.e., .php if you’re using PHP scripts or .html if you’re using HTML pages

1a. If not register\.php AND not checkout\.php AND %{SERVER_PORT} ^443$, redirect .*\.(php|html)$ to http://%{HTTP_HOST}%{REQUEST_URI}

1b. If register\.php OR checkout\.php AND %{SERVER_PORT} ^80$, redirect to https://%{HTTP_HOST}%{REQUEST_URI}

(Based on the way that Apache handled leading /'s with the introduction of Apache 2, your !/{whatever} should always be true. You’ve made the leading / optional in the html => php which is acceptable in both versions.)

That way, you don’t need to worry about support files

Problem:

#excludes directory from my rewrite rules
RewriteRule ^(admin|library|images|lab|blog|mailer|apps|media|phpmailer|partners|account|lib)($|/) - [L]

Sorry, that doesn’t It gives a passthrough which will probably be loopy (because it does nothing but match each time. If you want to excuse those directoreis from the following rules, use the Skip flag (as demonstrated in my signature’s tutorial when discussing flags).

RewriteRule (.*)/(.*)-(.*)/(.*)\\.html$ details.php?name=$2&storeID=$3&cmspage=$4
RewriteRule (.*)/(.*)-(.*)\\.html$ details.php?name=$2&storeID=$3

Oh, my! I don’t see anything major wrong but those are lacking the Last flags (probably not required) and the :kaioken: EVERYTHING :kaioken: atoms are known troublemakers as they’ll match EVERYTHING or NOTHING. The extra characters specified should keep you out of trouble but I prefer to specify the allowed characters to avoid unexpected problems.

#Regular Content Pages from CMS
RewriteRule ^/?([a-zA-z0-9_]+).html$ page.php?pg=$1

Same comments as above, i.e., if you know your Apache version use ^/ for Apache 1 or ^ for Apache 2. Your character range definition is fine but you’re again missing the Last flag. While not required, it should be (IMHO).

As for security of the scripts, I’d not worry about the support files (as long as you’re simply referencing them with relative links AND you’re not forcing them either to or away from %{HTTPS} on (server port 443 or 80).

Regards,

DK

I was able to run your code and find out what’s going on.

Let’s say you access [FONT=Courier New]https://www.domain.com/register.html[/FONT]. The redirect to non-https will be skipped, like you wanted, because your !^/register.html$ condition filters out this page. Apache then continues through the rest of the htaccess, and the last rule is applied, rewriting register.html to page.php?pg=register.

But this isn’t where things end. When the URI is internally rewritten, Apache reprocesses it as if it were a new request, which means your entire htaccess will execute again. But this time the URI will be page.php?pg=register, not register.html, which means your redirect to non-https won’t be skipped this second time around, and you end up with a redirect to page.php.

There are probably several ways to skin this cat. Here’s one that, off the top of my head, seems the simplest. There are several variables you can check against in conditions. The one you’re using right now is REQUEST_URI. But this variable won’t always represent the value in the browser’s address bar. It actually represents the URI that Apache is currently processing, which might have come from an internal subrequest, such as from a rewrite to page.php. If you want to ensure that you only ever check against the value as it appears in the browser’s address bar, then you’ll have to use the variable THE_REQUEST. Its value will look something like this:

GET /index.html HTTP/1.1

If we wanted to match against THE_REQUEST, then we could change your SSL conditions like so:

[FONT=Courier New]####-- Secure Socket Rewrite Conditions. ####

Allow some URIs to be https if requested

RewriteCond %{SERVER_PORT} ^443$
RewriteCond %{THE_REQUEST} !\s/register\.html\s
RewriteCond %{THE_REQUEST} !\s/checkout\.html\s

RewriteCond %{REQUEST_URI} !^/(.).css$
RewriteCond %{REQUEST_URI} !^/(.
).png$
RewriteCond %{REQUEST_URI} !^/(.).jpg$
RewriteCond %{REQUEST_URI} !^/(.
).js$
RewriteRule ^(.*) http://localhost/$1 [L,R]
####-- Secure Socket Rewrite Conditions. ####[/FONT]