Trying to tidy up .htaccess and remove hard-coding of domain name - apache

I have the below configurations set up in a .htaccess file.
Instead of hard-coding the domain name (domain.com), can I use the domain of the current request and prevent hard-coding of the domain name?
Also, is that safe? Hard-coding guarantees the correct domain of course, but I'm trying to think if the 'grab current domain name' method might cause other issues (especially with the first two examples below).
# Allow cross-domain requests
#
SetEnvIf Origin "^http(s)?://(.+\.)?(domain\.com)$" origin_is=$0
Header add Access-Control-Allow-Origin %{origin_is}e env=origin_is
Header add Access-Control-Allow-Credentials: true
# CSP
#
Header set Content-Security-Policy "default-src 'none'; connect-src http://domain.com https://domain.com;"
# Set domain name as a variable
#
RewriteRule .* - [E=domain_name:domain.com]
# Redirect non-secure (HTTP) traffic to secure (HTTPS)
#
RewriteCond %{ENV:HTTPS} !on [NC]
RewriteRule ^(.*)$ https://%{ENV:domain_name}/$1 [R=301,L]

You can just use %{HTTP_HOST} env variable which is already populated by Apache.
RewriteCond %{ENV:HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]

Related

Redirect all path except a few in htaccess

Id like to use the .htaccess file on an apache servier redirect all paths on a given domain to a new location but keep a few specific URLs live.
Redirect 301 /(.*) www.example.com
# but not /foo
# but not /bar
# but not /baz
You cannot do it using Redirect directive. I suggest using mod_rewrite:
RewriteEngine On
RewriteCond %{THE_REQUEST} !/(?:foo|bar|baz)[?/\s] [NC]
RewriteRule ^ http://www.example.com%{REQUEST_URI} [L,NE,R=301]
THE_REQUEST variable represents original request received by Apache from your browser and it doesn't get overwritten after execution of other rewrite directives. Example value of this variable is GET /index.php?id=123 HTTP/1.1

RewriteRule + HTTPS redirect for specific requests

I have setup the htaccess file to handle users requests with a specific rule and generic requests with other rules:
# users requests (i.e. users/login.html)
RewriteRule ^users/([^/]+)\.html$ mvc.php?rt=users/$1 [L,QSA,NC]
# generic requests (controller/action/id.html)
RewriteRule ^([^/]+)/([^/]+)/([^/]+)\.html$ mvc.php?rt=$1/$2&id=$3 [L,QSA,NC]
# generic requests (controller/action/)
RewriteRule ^([^/]+)/([^/]+)/$ mvc.php?rt=$1/$2 [L,QSA,NC]
# generic requests (controller/id.html)
RewriteRule ^([^/]+)/([^/]+)\.html$ mvc.php?rt=$1&id=$2 [L,QSA,NC]
# generic requests (controller.html)
RewriteRule ^([^/]+)\.html$ mvc.php?rt=$1 [L,QSA,NC]
RewriteRule ^$ mvc.php?rt=index [L,QSA,NC]
This works fine, and URL translation is handled correctly. My goal is now to force all users requests to be sent over HTTPS. I'm trying to setup a redirect rule as described in RewriteHTTPToHTTPS. I know this is not the recomended solution, but my server doesn't seem to support VirtualHost statements. Here is my code:
# users http to https
RewriteCond %{HTTPS} !=on
RewriteRule ^users(.*) https://%{SERVER_NAME}/users$1 [R,L]
Unfortunately this doesn't seem to work because I needed to insert the L flag after all rules, which causes the processing to stop when the rule is met. So, if the http-to-https rule is inserted first in htaccess, this rule is met and user specific rule is ignored (and viceversa for other case). Is there a way to both:
handle users requests with a specific rule
force users requests to be sent over HTTPS
with htaccess rules?
For many reasons my advice is to :
- do 301 redirect to https on all http requests
- use HSTS on all https answer
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
or
<VirtualHost *:80>
ServerAlias *
RewriteEngine On
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [redirect=301]
</VirtualHost>
And in the 443 Virtualhost :
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
WARNING : Set the Strict-Transport-Security ONLY when the https works on all webpage. You can try with 3600 (10 minutes) in the begining if you are not sure. The "includeSubDomains" will for https for all subdomains and "preload" will allow your website to be added to the preload list of browsers.
If you have a login page do not forget the Secure attribute on the cookies (without it the cookie will be sent with insecure http request too).
Why ?
- Because without HSTS someone can force the browser to do a request to http://example.com/mysecurepage and then intercept the http request before you answer a 301, and respond the same page than the one you respond, but with http links instead. This attack is called sslstrip and the only thing that can prevent it is HSTS (preloaded if possible)
- With HSTS protect you if you forgot to add the secure attribute on cookies (but not all browser know HSTS, that's why it's still important to use the secure attribute!)
- Because it's easy to miss which pages must be mark secure :
if a page ask for personal data (email, name, ...) then in most European country you have the obligation to secure it ; sometimes, a page do not ask personal data but display it ; sometime the fact that the content of the page is public do not mean the visitor accept that anyone know he visits it.
- With HTTP2 and SPDY encrypted page can be served faster than not encrypted one: https://istlsfastyet.com/

Redirect all HTTP to HTTPS

I have a SSL on my site and would like to redirect all my http pages to https
I find something below and work for www.yourdomain.com.
If I also need transfer all yourdomain.com(without www) to https what should I add to htaccess? Thanks!
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.yourdomain.com/$1 [R,L]
<!-- Please put the redirect without www here, thanks-->
A simple Google search reveals hundreds of results. For example, this official FAQ.
RewriteEngine On
# This will enable the Rewrite capabilities
RewriteCond %{HTTPS} !=on
# This checks to make sure the connection is not already HTTPS
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
# This rule will redirect users from their original location, to the same location but using HTTPS.
# i.e. http://www.example.com/foo/ to https://www.example.com/foo/
# The leading slash is made optional so that this will work either in httpd.conf
# or .htaccess context

http/https Rewrite not working, adds index.php to path

I'm trying to add some secure pages to a site. The links in the site all use the current protocol (i.e. are protocol independent, paths start with //).
I need the paths /info/season-tickets/* and /ticketcontroller/* to use https, and all others using http.
I've tried building rules to do the following (ignoring the ticketcontroller part for now):
If Port==80 and Path==/info/season-tickets/, rewrite with https
If Port==443 and Path!=/info/season-tickets/, rewrite with http
However, when I access /info/season-tickets/, rather than redirecting to the https version, I get example.com/index.php/info/season-tickets
The .htaccess is below - my attempts are below # Force https on certain pages and # Force http everywhere else, and the other bits are from the Kohana framework
# Turn on URL rewriting
RewriteEngine On
# Installation directory
RewriteBase /
# Force https on certain pages
RewriteCond %{SERVER_PORT} 80
RewriteCond %{REQUEST_URI} ^/info/season-tickets/?
RewriteRule ^(.*)$ https://www.example.com/$1 [R,L]
# Force http everywhere else
RewriteCond %{SERVER_PORT} 443
RewriteCond %{REQUEST_URI} !^/info/season-tickets/?
RewriteRule ^(.*)$ http://www.example.com/$1 [R,L]
# Protect hidden files from being viewed
<Files .*>
Order Deny,Allow
Deny From All
</Files>
# Protect application and system files from being viewed
RewriteRule ^(?:application|modules|system)\b index.php/$0 [L]
# Allow any files or directories that exist to be displayed directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Rewrite all other URLs to index.php/URL
RewriteRule .* index.php/$0 [PT]
I tried re-ordering the rules to see if that fixed it, but it didn't.
Any ideas why this isn't working (http://htaccess.madewithlove.be/ shows that it should work)...
Thanks!
I've solved this issue, not with htaccess, but in the index.php file (all requests go through this).
By default, I assume port 80. Then, if $_SERVER['REQUEST_URI'] is in an array of secure paths, I switch the variable to 443.
Then, if $required_port != $_SERVER['SERVER_PORT'], I redirect and exit().

Apache RewriteCond ignored in case of https

I have to redirect from one domain to another domain. Both the domains have http and https protocol enabled. so in order to map http and https i have tried various combinations in conf file as below:
#RewriteCond %{HTTPS} =on
#RewriteCond %{SERVER_PORT} ^443$
#RewriteRule ^(.+)$ - [env=askapache:https]
#RewriteCond %{HTTPS} !=on
#RewriteRule ^(.+)$ - [env=askapache:http]
RewriteCond %{SERVER_PORT}s ^(443(s)|[0-9]+s)$
RewriteRule ^(.+)$ - [env=askapache:%2]
RewriteCond %{HTTP_HOST} ^([www.]+)?test-redirect\.com$ [NC]
RewriteRule ^(.*)$ http%{ENV:askapache}//amit.test.com/content/test/category/6 [L]
#RewriteCond %{HTTP_HOST} ^([www.]+)?test-redirect\.com$ [NC] <BR>
#RewriteCond %{HTTPS} !on
#RewriteRule .? http://amit.test.com/content/test/category/6 [L]`
But every time https condition is skipped/ignored. there is nothing rewrite logs as well. i have seen so many examples on net. but fail to understand why it is not detecting https? where http is working perfectly fine.
Rewrite logs may very well be in 2 diff locations for https and http. You can try using HTTP_AA instead of using "askapache" for the name of the env. The prefix HTTP_ANYTHING is a more fail safe way to make sure the var is available since some setups don't allow custom vars that start with anything other than HTTP_ which they have to allow due to it represents a HTTP header usually.
Make sure your https port is actually 443 or you will need to change the code.
Make sure your mod_rewrite block of code works by trying the first and second methods here: Even Newer HTTP/HTTPS Rewrite Code If it doesn't work using the first example you need to get it working using that rule first.
Try setting the HTTP_AA var above the rewrite code using the SetEnvIfNoCase directive or with
SetEnv HTTP_AA
Verify your vhost/httpd.conf settings for both SSL and non-SSL like the document root and Options and AllowOverrides, Logs and maybe StdEnvVars for SSLOptions.
Build a shtml file using mod_includes that just does a printenv. Then view both the ssl and non-ssl outputs and pay particular attention to the vars with the prefix REDIRECT_ and obviously make sure the HTTP_AA var shows up correctly in the printenv output. Or you could use the printenv cgi script or the shtml example on the askapache site.
Don't forget http://httpd.apache.org/.
Or try this
Options +FollowSymLinks +ExecCGI
# Set var now to try to try to have it availabe for mod_rewrite
SetEnv HTTP_AA
RewriteEngine On
RewriteBase /
# HTTP_AA is set to either s or is blank
RewriteCond %{SERVER_PORT}s ^(443(s)|[0-9]+s)$
RewriteRule ^(.+)$ - [env=HTTP_AA:%2]
# if host not new domain, its old so redirect both http/https to new
RewriteCond %{HTTP_HOST} !^amit\.example\.com$ [NC]
RewriteRule .* http%{ENV:HTTP_AA}://amit.example.com/content/test/category/6 [R=301,L]