Limiting HTTPS to specific application routes - ssl

I have an application that uses routing rules to define actions for users, and specific entity types. Is it possible to create a specific set of rules for Apache's SSL implementation to permit specific paths on the site to use HTTPS, with other routing rules using HTTP? The current routing rules are a basic argument reformat:
<Directory "/var/www/exampleapp/public/">
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?_url=/$1 [QSA,L]
</Directory>
All application behavior is being served on a VirtualHost on port 80.

There could be a few ways to do this, one way is given below.
Assuming all your requests are arriving on https, you can do the following :
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/uri1 [NC]
RewriteCond %{REQUEST_URI} ^/uri2 [NC]
..
..
RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI} [L,R]
In this case, you are listing the uri's that you need on https and are redirecting the remaining to http
You can always switch it around

Related

Redirect domain to other domains subdirectory but show first domain in address bar?

I'd like to redirect "abc.com" to "xyz.com/abc" but still, show "abc.com" in the browser's address bar. As far as I understand you'd be using rewrite rules to achieve this.
I own both domains and both pages are on the same server.
Its an ionos webserver. The website itself is located in
/clickandbuilds/mywebsite (lets say this is "xyz.com")
Now there is a subpage on this website ("xyz.com/my-landing-page")
that is also accessible over its own domain (lets say "abc.com")
Right now im using a simple http redirect and all requests to "abc.com get redirected to "xyz.com/my-landing-page". This is the exact thing that I want but I do not want to show the url of the landing-page but the top-level-domain (xyz.
How would this condition look like?
htaccess:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
AddHandler x-mapp-php5.5 .php
# BEGIN rlrssslReallySimpleSSL rsssl_version[3.3.5]
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTPS} !=on [NC]
RewriteCond %{REQUEST_URI} !wp-content\/cache\/(all|wpfc-mobile-cache)
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
You have two obvious options, which one is better for you depends a bit on the specific situation:
an internal rewriting strategy:
You need to take care that the rewriting module is actually loaded into the http server. Then you can implement that rule:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^abc\.com$
RewriteCond %{REQUEST_URI} !^/abc
RewriteRule ^ /abc%{REQUEST_URI} [QSA,END]
This approach can be implemented in the actual http server's host configuration (which should be preferred) or in a distributed configuration file (".htaccess") in case you do not have access to the real configuration (read: if you are using a cheap hosting provider).
an internal proxy strategy:
Instead of using the rewriting module you could directly use the proxy module:
ProxyPass / https://example.com/abc/
ProxyPassReverse / https://example.com/abc/
This needs to be implemented in the actual http server's host configuration, however. So you'd need access to that.
The same could be achieved using the rewriting module (which uses the proxy module internally). This would allow to use distributed configuration file (".htaccess") for this approach too:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^abc\.com$
RewriteCond %{REQUEST_URI} !^/abc
RewriteRule ^ https://example.com/abc%{REQUEST_URI} [P]
Both proxy based options share the disadvantage that performance is an issue due to the fact that you need a full additional internal http request for each and every incoming request.
In general the first approach makes more sense, out of performance reasons. This has to be supported by your application logic however: this will only work if your application uses relative references ("links"). If it uses absolute URLs instead and you cannot change that you will need to dive into the second approach.

htacess redirect subsomains to root domain and force www

Hi I have an annoying issue that I am trying to redirect all subdomains to root domain and force www. At the moment it forces www as needed but if I go to sub.example.dom I am able to and this is what I am trying to prevent. Here is my htaccess file.
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example.com$
RewriteRule (.*) http://www.example.com/$1 [R=301,L]
RewriteRule ^service-description/([+a-zA-Z0-9]+)/([+a-zA-Z0-9]+)\.html$ /location.php?city=$1&process=$2 [L]
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
The direct approach is to add another rewriting rule that redirects all requests to host names not starting with www:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example\.com$
RewriteRule ^/?(.*)$ https://www.example.com/$1 [R=301]
RewriteCond %{HTTP_HOST} !^www\.example\.com$
RewriteCond %{HTTP_HOST} ^.*\.example\.com$
RewriteRule ^/?(.*)$ https://www.example.com/$1 [R=301]
You can actually simplify this if your http server does not answer to other second level domains or if you want to redirect all requests regardless of which host name they target:
RewriteEngine on
RewriteCond %{HTTP_HOST} !^www\.example\.com$
RewriteRule ^/?(.*)$ https://www.example.com/$1 [R=301]
Those rule sets will work likewise in the http servers host configuration or inside a dynamic configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and in case you use a dynamic configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.
And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using dynamic configuration files (".htaccess"). Those dynamic configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).

Force HTTPS / Mod-rewrite behind reverse proxy (with WordPress)

Forgive my lack of knowledge in this area.
First, our situation: We have a reverse proxy setup where we have http://www.xxx.ca/x and sometimes http://www.xxx.ca/x/y is forwarded to http://xxx1a.xxx.ca/x or http://xxx1a.xxx.ca/x/y
We have been trying to create a generic .htaccess where we do not have to define any subdirectories specifically. Basically, we can use this .htaccess on 100's of sites without modifying the file on a site by site basis.
We have gotten this part working. However, we are unable to force https. Every example I see uses HTTP_HOST, which returns the value of the proxied server - not the original request.
Perhaps there is a completely different solution to what we have setup, but my knowledge of apache is limited. Below is what we currently have - which solves the generic sub-folder issue, but not the HTTPS issue.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{ENV:URI} ^$
RewriteRule ^(.*)$ - [ENV=URI:$1]
RewriteCond %{ENV:BASE} ^$
RewriteCond %{ENV:URI}::%{REQUEST_URI} ^(.*)::(.*?)\1$
RewriteRule ^ - [ENV=BASE:%2]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . %{ENV:BASE}index.php [L,QSA]
</IfModule>
I am completely willing to change 100% of this if there is a better solution.
I'm not sure I have understood when you have to redirect the user to https. Anyway, when you have to switch to https, you could just check SERVER_PORT server internal variable and if is not 80 then redirect:
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{ENV:URI}/$1 [L,R=301]

Redirect loop when redirecting to HTTPS in XCART

There are other posts discussing HTTP to HTTPS redirection but none of hem answer this question.
I have an XCART website and want to direct ALL traffic to https in the htaccess file.
The rewrite section currently looks like this, which I believe is the xcart method of enabling clean uls. Note I have commented out the HTTPS redirection code.
<IfModule mod_rewrite.c>
RewriteEngine On
# RewriteCond %{HTTPS} =off [NC]
# RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteBase /
RewriteCond %{REQUEST_URI} !^/(payment|admin|provider|partner)/
RewriteCond %{REQUEST_FILENAME} !\.(gif|jpe?g|png|js|css|swf|php|ico)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*)$ dispatcher.php [L]
</IfModule>
If I uncomment the HTTPS redirection condition & rule I get a redirect loop when trying to load any HTTP urls. I have tried lots of variations - putting the redirect after the second rule, changing the syntax. Nothing works. Perhaps it isn't possible to combine the XCART clean url feature (redirecting to dispatcher.php) with a universal HTTP to HTTPS redirection.
In the meantime, I have included the following HSTS header which forces temporary HTTPS usage but which isn't a redirect. I'd prefer a redirect...
Header set Strict-Transport-Security "max-age=31536000" env=HTTPS

override apache rewrite rules with htaccess

working on a server that hosts multiple domains.
Somewhere in apache config is a rewrite rule that is set for ALL domains.
What happens is if a user goes to example.com/foo they are supposed to get redirected to example.com/foo_bar
However, in one domain, I want to override this behavior so that the url stays at example.com/foo and does not redirect. I've been searching and trying various rules and conditions to no avail. I don't have access to the apache config, but I am using .htaccess for some rewrite rules on this domain.
here's my rewrite rules in .htaccess:
<IfModule mod_rewrite.c>
RewriteEngine on
# this isn't working
# RewriteRule ^(foo)($|/) - [L]
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?/$1
# this didn't work either
# RewriteRule ^/foo index.php?/$1 [L]
</IfModule>
Try redirecting /foo_bar back to /foo.
When Apache processes the rewrite rules it runs through them multiple times, which you can see when you turn on debugging. I think what's happening in your case is that you're trying to match the URI in the first pass, but Apache has already modified it to /foo_bar.
Also, as a matter of debugging, you should try to recreate the problem in an environment you control. Ask your sysadmin for a copy of the global configuration and mirror the set up you're constrained to.
You can create exception for one domain:
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} !^(?:www\.)?domain\.com$ [NC]
RewriteRule ^foo(/.*)?$ /foo_bar$1 [L,R=302]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?/$1 [L,QSA]