#1
  1. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2002
    Location
    Bay Area California
    Posts
    371
    Rep Power
    14

    Issues with Google Chrome and RewriteRule (mod_rewrite) - need solution


    Hi all,

    Last week I was working on a way to automatically redirect certain pages in my Web site to HTTPS while directing all other pages (not needing security) back to HTTP.

    I was able to do this successfully with the help I received in this forum thread.

    Yesterday, I was told by a prospective client that when they visited our "sign-up" form using Google's Chrome Web browser, they are getting a completely blank page. Sure enough, I tested this with the latest version of Chrome on OSX and Windows 7 and got a blank signup page. It works great in Safari, Firefox, and IE, just not Chrome. Further research into how Chrome handles SSL security shows that is is even more strict than IE, and simply won't display mixed content at all.

    Looking at the Chrome debug console showed that the signup.php script was trying to load insecure and secure content. It listed all of my style sheets, Javascript, etc. as insecure. This really confused me since all of those files are relative links in the <head> of the Web page and should be loaded using the same protocol of the base file????

    I finally tracked down the issue by commenting out all of the ReWrite rules I had added to Apache, and then visiting the page in Chrome again using HTTPS... Lo and behold and it worked fine. This got me thinking...

    It appears that due to my set of rewrite rules in my httpd.conf file:
    PHP Code:
           <Directory "/Library/WebServer/Documents/mysite">
                   
    Options +FollowSymLinks
                   RewriteEngine On
                   RewriteCond 
    %{HTTPSon
                   RewriteRule 
    !^(signup|signup_process|signup_conf|setup_co_and_user).phphttp://%{HTTP_HOST}%{REQUEST_URI} [L,R]
           
    </Directory>

           <
    Directory "/Library/WebServer/Documents/mysite">
                   
    Options +FollowSymLinks
                   RewriteEngine On
                   RewriteCond 
    %{HTTPSoff
                   RewriteRule 
    ^(signup|signup_process|signup_conf|setup_co_and_user).phphttps://%{HTTP_HOST}%{REQUEST_URI} [L,R]

           
    </Directory
    ... any of the include files or <link> files were being rewritten by mod_rewrite to insecure HTTP even though the RewriteRule above tells apache NOT to rewrite my signup files. Included files of an ignored file must be treated differently. So the rewrite rules are apparently not only working on the base file in the directory, but also on any other included file that that file refers to - even if that file was a relative link or include file...

    This seems awfully strange? Can anyone verify that the mod_rewrite rules not only apply to the base file but to any file that base file refers to at the time it is requested by the browser.

    The whole reason to do this in the first place was to (1) ensure I can use relative links throughout my site and (2) ensure that certain scripts are always secured, even if the user tries to change the protocol back to HTTP.

    The solution seems to be the following:
    (*) Tell mod_rewrite to NOT rewrite the include files back to HTTP such as my CSS and Javascript include files called in my secure programs. Can this be done?

    Maybe there a way to tell mod_rewrite to not traverse all the subdirectories of the directory I specify when it applies its rules? Basically I only want mod_rewrite to look at the files in my root "/Library/Webserver/Documents/mysite" and not all of the subdirectories under /mysite/ such as "/images" , "/includes" , and "/css". This just seems to be getting messy now.

    The normal hypertext protocol handler would make any of my relative linked include files secure when the base file is loaded securely, so I really don't want all of my support files to be subject to redirects with mod_rewrite. I sure hope this is possible.

    Thanks for the help.
  2. #2
  3. Come play with me!
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    13,746
    Rep Power
    9397
    Originally Posted by jkoerber
    This seems awfully strange? Can anyone verify that the mod_rewrite rules not only apply to the base file but to any file that base file refers to at the time it is requested by the browser.
    They apply to every single thing requested by the browser: PHP pages, CSS files, images... whatever. It's all equally edible. Er, all treated the same.


    Originally Posted by jkoerber
    The solution seems to be the following:
    (*) Tell mod_rewrite to NOT rewrite the include files back to HTTP such as my CSS and Javascript include files called in my secure programs. Can this be done?
    Yes, but I wouldn't advise it.

    Originally Posted by jkoerber
    Maybe there a way to tell mod_rewrite to not traverse all the subdirectories of the directory I specify when it applies its rules? Basically I only want mod_rewrite to look at the files in my root "/Library/Webserver/Documents/mysite" and not all of the subdirectories under /mysite/ such as "/images" , "/includes" , and "/css". This just seems to be getting messy now.
    That's what I would do, considering how you seem to have those files cleanly separated into directories. Allow those kinds of files to be accessed via HTTP or HTTPS without redirects.
    It's not messy:
    Code:
    <Directory "/Library/WebServer/Documents/mysite">
    	Options +FollowSymLinks
    
    	RewriteEngine On
    
    	# HTTPS-only pages
    	RewriteCond %{HTTPS} on
    	RewriteRule !^(signup|signup_process|signup_conf|setup_co_and_user).php$ http://%{HTTP_HOST}%{REQUEST_URI} [L,R]
    
    	# don't do anything to images and CSS and such
    	RewriteRule ^(images|includes|css)/ - [L]
    
    	# everything else is HTTP-only
    	RewriteCond %{HTTPS} off
    	RewriteRule ^(signup|signup_process|signup_conf|setup_co_and_user).php$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R]
    </Directory>
    (using a "-" as the substitution URL tells mod_rewrite to not change anything)

    Also,
    - You don't need multiple <Directory>s if they're all for the same thing
    - You don't need multiple Options
    - Since you're combining stuff the duplicate RewriteEngine can go away

    Comments on this post

    • jkoerber agrees : Good direction on the suggestion provided
  4. #3
  5. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2002
    Location
    Bay Area California
    Posts
    371
    Rep Power
    14
    requinix,

    Thanks again for the response and for the very helpful tips. I implemented the code you provided in your last response, but unfortunately it only partially works. We are really close on this, but something is still causing mixed content on some pages.

    If I completely implement your <directory> code from the last post, my site manages to correctly convert all HTTPS traffic, excluding the 4 special files, back to HTTP and it seems to be honoring NOT rewriting anything in my /images/ or /includes/ subdirectories (I assume that also means any sub-sub-dirtectories of those too). But I am still getting the errors about mixed content when I click to my signup.php screen. It still shows all of the /include/ and /images/ files being served as insecure files, even though we told it to ignore those directories??

    I basically hacked and hacked around with dozens of combinations of the code you provided, moving some items around, and finally got a working version (probably by sheer bull-headed force). I have fully tested this end-to-end and am happy with the results. It may not be pretty, but it works. Here is the version in the httpd_443.conf file:
    Code:
    # JCK 2012-10-29 added to set up redirect back to insecure #################
    	<Directory "/Library/WebServer/Documents/mysite">
    		Options +FollowSymLinks
    		RewriteEngine On
    
    		### HTTPS-only pages ###
    		RewriteCond %{HTTPS} on
    		RewriteRule ^(includes|images)/ - [L]
    		RewriteRule !^(signup|signup_process|signup_conf|setup_co_and_user).php$ http://%{HTTP_HOST}%{REQUEST_URI} [L,R]
    	</Directory>
    # JCK 2012-11-07 had to add this subdirectory as it was being rewritten by other rules otherwise
    	<Directory "/Library/WebServer/Documents/mysite/signup">
    		Options +FollowSymLinks
    		RewriteEngine On
    		RewriteCond %{HTTPS} on
    		RewriteRule ^(includes|images)/ - [L]
    		RewriteRule !^setup_co_and_user.php$ http://%{HTTP_HOST}%{REQUEST_URI} [L,R]
    	</Directory>
    You'll note, I had to create a second <directory> for the /mysite/signup/ because the "setup_co_and_user.php" file lives in that sub-directory and it was not honoring the rules from the prior section without it?? I thought these rules were inherited by all subdirectories, but it does NOT appear that is true.

    Here is the <directory> code for the httpd_80.conf file:
    Code:
            <Directory "/Library/WebServer/Documents/mysite">
                    Options +FollowSymLinks
                    RewriteEngine On
    
                    ### For all HTTP content ###
                    RewriteCond %{HTTPS} off
                    RewriteRule ^(signup|signup_process|signup_conf|setup_co_and_user).php$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R]
            </Directory>
    I probably didn't mention my Apache2 configueration loads different httpd.conf files for the secure and insecure parts of this Web site. That may have been one of the reasons for the difficulty, or not. I'm not sure.

    Again, thanks hugely for your help. I now have a fully functioning version that manages my site perfectly - and it works under Google Chrome and IE (the red-headed stepchildren of Web browsers).

    If you have any additional comments on the above solution, I am all ears.

    Cheers!

IMN logo majestic logo threadwatch logo seochat tools logo