Content Security Policy causing CORS errors - .htaccess

weird one but the referer policy is currently creating issues on my website if the domain has a . on the end, for example:
domain.uk - works fine
domain.uk. - has CORS errors
It seems the . on the end os being treated as part of the domain so considered a different origin. Seems to only be a problem in Chrome. Possibly a Chrome bug?
Thought perhaps I could fix this in my .htaccess by setting up a redirect, but the .htaccess cannot do it as it can only match after the domain, and the . is being treated as part of the domain.
Any suggestions?

It seems the . on the end os being treated as part of the domain so considered a different origin. Seems to only be a problem in Chrome. Possibly a Chrome bug?
It is part of the domain. The trailing dot indicates a fully qualified domain name. If you are only seeing different behaviour in Chrome then maybe Chrome is just being more strict - it's not a bug.
Try https://stackoverflow.com./ (for instance) - you'll probably appear logged out (as the cookies are not passed).
Thought perhaps I could fix this in my .htaccess by setting up a redirect, but the .htaccess cannot do it as it can only match after the domain, and the . is being treated as part of the domain.
You can do it in .htaccess. The dot is sent as part of the Host header (since it is part of the domain) - which is available in the HTTP_HOST server variable. Ordinarily, you'd do this as part of your canonical (www vs non-www / HTTP to HTTPS) redirect, but you could do something like the following using mod_rewrite to remove the trailing dot on the requested hostname:
RewriteEngine On
RewriteCond %{HTTP_HOST} (.+)\.$
RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L]
The %1 backreference contains the hostname, less the trailing dot, that is captured in the preceding condition.
UPDATE:
I am using Wordpress so it already has some rewrite rules in the htaccess, ... can you advise on how to add your rewrites
You need to place this redirect before the existing WordPress directives (ie. before the # BEGIN WordPress section), near the top of the file.
You do not need to repeat the RewriteEngine On directive since that already occurs later in the WordPress section. (If there are multiple RewriteEngine directives then the last instance wins and controls the entire file.)

Related

.htaccess adds /var/www/html

We have had our Website running on an older Apache2 instance with a large .htaccess file for redirects of old URLs to new ones. Since we have a lot of equal sub-URLs the redirect looks like this:
RewriteRule ^(.*)old/url(.*)$ new/url [L,R=301]
This worked like a charm.
For example www.example.com/a/old/url got redirected to www.example.com/a/new/url and also worked for /b/ or /c/.
With the new Apache (2.4.54) the redirect doesn't work as expected since it redirects as follows:
www.example.com/var/www/html/new/url
What am I doing wrong? Why does it place the base path of the website in front?
I've tried to google as good as possible but couldn't find anything. I would expect any weird path that I don't know of is set in the wrong way.
I'm not very deep into .htaccess which makes it hard to troubleshoot.
RewriteRule ^(.*)old/url(.*)$ new/url [L,R=301]
This worked like a charm.
For example www.example.com/a/old/url got redirected to www.example.com/a/new/url and also worked for /b/ or /c/.
It would only do that if you also had a RewriteBase /a directive defined elsewhere in the config file. (Although it's not clear how it would work the same for /b/ or /c/, unless you have other directives that are helping. Unless you mean that it redirects from /b/ or /c/ to /a/? In which case, the RewriteBase directive alone is what is enabling this to work.)
With the new Apache (2.4.54) the redirect doesn't work as expected since it redirects as follows: www.example.com/var/www/html/new/url
That will happen if RewriteBase is not defined as mentioned above.
This applies to both Apache 2.2 and 2.4.
However, it's also possible that RewriteBase is/was defined in a parent config and RewriteOptions MergeBase was set (which propagates the setting to child configs). A further complication is that in later versions of Apache 2.2 (specifically 2.2.23 and later) and early versions of Apache 2.4 (specifically 2.4.0 to 2.4.3) this was actually the default (arguably buggy) behavior. So, if you are upgrading from one of these "buggy" versions of Apache, it's possible this was "just working".
The RewriteBase directive defines the URL-path that is prefixed to relative substitution strings (new/url is a relative substitution string). If no RewriteBase is defined then the directory-prefix (ie. the absolute file-path of where the .htaccess file is located) is added back - which is resulting in your malformed redirect.
For external "redirects" it is often preferable to use a root-relative (starting with a slash) or absolute (scheme + hostname) substitution string. For example:
RewriteRule ^(.*)old/url(.*)$ /a/new/url [L,R=301]
The above is no longer dependent on the RewriteBase directive, since the substitution string (ie. /a/new/url) is no longer relative.
However, ^(.*)old/url(.*)$ is the same as simply old/url, which is rather too general. Perhaps something like the following would be preferable:
RewriteRule ^(a|b|c)/old/url /a/new/url [L,R=301]
The above redirects /a/old/url or /b/old/url or /c/old/url<anything> to /a/new/url.
OR, redirect to the same URL-path (ie. a, b or c) using a backreference:
RewriteRule ^(a|b|c)/old/url /$1/new/url [L,R=301]
You will need to clear your browser cache before testing, since the erroneous 301 (permanent) redirect will have been cached by the browser (and possibly any intermediary caches). Test first with 302 (temporary) redirects to avoid potential caching issues.
Reference:
https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewritebase
https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewriteoptions
https://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewriteoptions

HTACCESS 301 redirect keep sending to the wrong page

I am trying to redirect an old page from a website I have redesigned, to the new one, but it's not working.
Here's my 2 lines of code in the .htaccess file regarding that domain:
Redirect 301 /deaneco http://solutionsgtr.ca/fr/deaneco/accueil.html
RewriteRule ^/deaneco/contact http://solutionsgtr.ca/fr/deaneco/contact.html [R=301,L,QSA]
If go on the solutionsgtr.ca/deaneco/contact URL, it gives me the following page:
http://solutionsgtr.ca/fr/deaneco/accueil.html/contact
The first rule works though (deaneco/ to solutionsgtr.ca/fr/deaneco/accueil.html).
I feel like both lines are being mixed together and are giving me the wrong page, that doesn't exist so I get a 404 error.
There are a couple of issues here:
The Redirect directive (part of mod_alias) is prefix-matching and everything after the match is appended on the end of the target URL. This explains the redirect you are seeing.
The RewriteRule (mod_rewrite) pattern ^/deaneco/contact will never match in a .htaccess context since the URL-path that is matched does not start with a slash. So, this rule is not doing anything currently.
You should avoid mixing redirects from both modules since they execute independently and at different times during the request (mod_rewrite executes first, despite the apparent order of the directives).
Either use mod_alias, ordering the directives most specific first:
Redirect 301 /deaneco/contact http://solutionsgtr.ca/fr/deaneco/contact.html
Redirect 301 /deaneco http://solutionsgtr.ca/fr/deaneco/accueil.html
NB: You will need to clear your browser cache, since the erroneous 301 (permanent) redirect will have been cached by the browser. Test with 302 (temporary) redirects to avoid potential caching issues.
OR, if you are already using mod_rewrite for other redirects/rewrites then consider using mod_rewrite instead (to avoid potential conflicts as mentioned above):
RewriteEngine On
RewriteRule ^deaneco/contact$ http://solutionsgtr.ca/fr/deaneco/contact.html [R=301,L]
RewriteRule ^deaneco$ http://solutionsgtr.ca/fr/deaneco/accueil.html [R=301,L]
The QSA flag is not required, since the query string is passed through to the substitution by default.
The order of the RewriteRule directives are not important in this instance, since they match just that specific URL.
If go on the solutionsgtr.ca/deaneco/contact URL
If you are redirecting to the same host then you don't need to explicitly include the scheme + hostname in the target URL, since this will default.

How can I mask a domain using .htaccess?

We have the following situation:
We would like to setup a domain masking to provide content from a project platform to an end user. The end user has setup a CNAME record from player.domain-client.com. to app.domainA.com
Now when the end user enters https://player.domain-client.com/5432 he should get the contents of https://app.domainA.com/player/?=5432.
But the URL should remain https://player.domain-client.com/5432.
This masking should only by applied if the client subdomain contains player.
Could anybody point me to the right direction on how to setup the .htaccess so it does the correct masking?
The end user has setup a CNAME record from player.domain-client.com. to app.domainA.com
Presumably the "project platform" has also been configured to accept requests to player.domain-client.com?
In which case, it should just be a matter of a simple internal rewrite (on the same host). Although, if you would ordinarily request the same URL-path at app.domainA.com , ie. app.domainA.com/5432, then there is nothing you need to do as the rewrite is already in place? Otherwise, try the following:
RewriteEngine On
# Rewrite any request for /<number> to player/?=<number>
RewriteCond %{HTTP_HOST} ^player\. [NC]
RewriteRule ^(\d+)$ player/?=$1 [L]
However, /player/?=5432 isn't the actual endpoint as this requires further rewriting by the system for it to "work". Perhaps you mean something like /player/index.php?=5432? (The query string is also a little weird as you are missing a parameter name? As written, this would possibly require manual parsing of the query string to extract the value?)
The condition (RewriteCond directive) ensures that only requests to the player subdomain are rewritten.
On WordPress you need to make sure these directives go before the WP front-controller. ie. Before the # BEGIN WordPress section. The order of directives in .htaccess is important.
However, if this is all being managed by WordPress then you can't simply create a rewrite in .htaccess since WordPress still sees the original URL that was requested, not the rewritten URL. So, unless the requested URL exists as a valid route in WordPress itself then you'll likely get a 404. This sort of rewrite needs to be managed inside WordPress itself.
Alternative solution using a reverse proxy
An alternative is to configure your server as a reverse proxy and proxy the request from https://player.domain-client.com/1234 to https://app.domainA.com/player/?vid=1234 (mentioned in comments). Ideally this requires access to the main server config to config properly (requires mod_proxy and ProxyPass, ProxyPassReverse directives set appropriate in the virtual host).
Then, in .htaccess you would do something like the following instead, making use of the P flag on the RewriteRule:
# Proxy any request for /<number> to player/?=<number>
# for the "player" subdomain only.
RewriteCond %{HTTP_HOST} ^player\. [NC]
RewriteRule ^(\d+)$ https://app.domainA.com/player/?vid=$1 [P]

Simple and neat .htaccess redirect help required

This is a strange one...
A while back I managed to write a .htaccess redirect that worked so that the URL was read like: www.website.com/mt?page=index - and what the real URL of this page was www.website.com/PageParser.php?file=index.php
The problem has been that the FTP system of my webhost hides .htaccess files even though they are allowed and do operate - and so I have checked back on local copies I have of my .htaccess files and none of them have the code as to how this works - and I've forgotten how I did it!!
Essentially, I am using wildcards so that anything after mt?page= will actually be showing PageParser.php?file= but without having the PageParser.php showing within the URL (and this is the important bit, because the index.php on my site root is actually sent through PageParser.php first so that anything which shouldn't be there is wiped out before the end user sees it) - so how can .htaccess redirect/rewrite the URL so that any link to /mt?page= show the file located at /PageParser.php?file= without changing the URL the user sees?
RewriteEngine On
RewriteRule ^(.*)mt?page=(.*)$ $1PageParser.php?file=$2
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} ^page=([^&]+)
RewriteRule ^mt$ /PageParser.php?file=%1.php [NC,L]
This rule will rewrite (internal redirect) request for /mt?page=hello to /PageParser.php?file=hello.php without changing URL in browser.
Your source URL example (www.website.com/mt?page=index) has index while target URL (www.website.com/PageParser.php?file=index.php) has index.php. The above rule will add .php to the page name value, so if you request /mt?page=hello.php it will be rewritten to /PageParser.php?file=hello.php.php.
If there is a typo in your URL example and page value should be passed as is, then remove .php bit from rewrite rule.
The rule will work fine even if some other parameters are present (e.g. /mt?page=hello&name=Pinky) but those extra parameters will not be passed to rewritten URL. If needed -- add QSA flag to rewrite rule.
This rule is to be placed in .htaccess in website root folder. If placed elsewhere some small tweaking may be required.
P.S.
Better write no explanation (I knew it/I did it before .. but now I forgot how I did it) than having these "excuses". While it may be 100% true, it just does not sound that great.

How do I use .htaccess to redirect to a URL containing HTTP_HOST?

Problem
I need to redirect some short convenience URLs to longer actual URLs. The site in question uses a set of subdomains to identify a set of development or live versions.
I would like the URL to which certain requests are redirected to include the HTTP_HOST such that I don't have to create a custom .htaccess file for each host.
Host-specific Example (snipped from .htaccess file)
Redirect /terms http://support.dev01.example.com/articles/terms/
This example works fine for the development version running at dev01.example.com. If I use the same line in the main .htaccess file for the development version running under dev02.example.com I'd end up being redirected to the wrong place.
Ideal rule (not sure of the correct syntax)
Redirect /terms http://support.{HTTP_HOST}/articles/terms/
This rule does not work and merely serves as an example of what I'd like to achieve. I could then use the exact same rule under many different hosts and get the correct result.
Answers?
Can this be done with mod_alias or does it require the more complex mod_rewrite?
How can this be achieved using mod_alias or mod_rewrite? I'd prefer a mod_alias solution if possible.
Clarifications
I'm not staying on the same server. I'd like:
http://example.com/terms/ -> http://support.example.com/articles/terms/
https://secure.example.com/terms/ -> http://support.example.com/articles/terms/
http://dev.example.com/terms/ -> http://support.dev.example.com/articles/terms/
https://secure.dev.example.com/terms/ -> http://support.dev.example.com/articles/terms/
I'd like to be able to use the same rule in the .htaccess file on both example.com and dev.example.com. In this situation I'd need to be able to refer to the HTTP_HOST as a variable rather than specifying it literally in the URL to which requests are redirected.
I'll investigate the HTTP_HOST parameter as suggested but was hoping for a working example.
It's strange that nobody has done the actual working answer (lol):
RewriteCond %{HTTP_HOST} support\.(([^\.]+))\.example\.com
RewriteRule ^/terms http://support.%1/article/terms [NC,QSA,R]
To help you doing the job faster, my favorite tool to check for regexp:
http://www.quanetic.com/Regex (don't forget to choose ereg(POSIX) instead of preg(PCRE)!)
You use this tool when you want to check the URL and see if they're valid or not.
I think you'll want to capture the HTTP_HOST value and then use that in the rewrite rule:
RewriteCond %{HTTP_HOST} (.*)
RewriteRule ^/terms http://support.%1/article/terms [NC,R=302]
If I understand your question right, you want a 301 redirect (tell browser to go to other URL).
If my solution is not the correct one for you, try this tool: http://www.htaccessredirect.net/index.php and figure out what works for you.
//301 Redirect Entire Directory
RedirectMatch 301 /terms(.*) /articles/terms/$1
//Change default directory page
DirectoryIndex
According to this cheatsheet ( http://www.addedbytes.com/download/mod_rewrite-cheat-sheet-v2/png/ ) this should work
RewriteCond %{HTTP_HOST} ^www\.domain\.com$ [NC]
RewriteRule ^(.*)$ http://www.domain2.com/$1
Note that i don't have a way to test this so this should be taken as a pointer in the right direction as opposed to an explicit answer.
If you are staying on the same server then putting this in your .htaccess will work regardless of the server:
RedirectMatch 301 ^/terms$ /articles/terms/
Produces:
http://example.com/terms -> http://example.com/articles/terms
or:
http://test.example.com/terms -> http://test.example.com/articles/terms
Obviously you'll need to adjust the REGEX matching and the like to make sure it copes with what you are going to throw at it. Same goes for the 301, you might want a 302 if you don't want browsers to cache the redirect.
If you want:
http://example.com/terms -> http://server02.example.com/articles/terms
Then you'll need to use the HTTP_HOST parameter.
You don't need to include this information. Just provide a URI relative to the root.
Redirect temp /terms /articles/terms/
This is explained in the mod_alias documentation:
The new URL should be an absolute URL beginning with a scheme and hostname, but a URL-path beginning with a slash may also be used, in which case the scheme and hostname of the current server will be added.
It sounds like what you really need is just an alias?
Alias /terms /www/public/articles/terms/

Resources