Escaping chars in .htaccess
Solution 1:
.htaccess
supports much more than only mod_rewrite
directives.
This lists all directives Apache supports and if they are allowed in .htaccess
files https://httpd.apache.org/docs/2.4/mod/quickreference.html
Not every directive that is allowed in .htaccess has the same rules / requirements for escaping “special” characters as many are NOT regular expressions. Typically the manual will list which rule set governs a directive
Of interest may be
https://httpd.apache.org/docs/2.4/expr.html
https://httpd.apache.org/docs/2.4/rewrite/intro.html#regex
Solution 2:
does anyone have list which chars should be escaped?
You will not find a simple list.
Whether specific chars need to be escaped in .htaccess
(or Apache config files in general) is dependent on context (module/directive and argument) and what it is you want to do (use the meta-characters special meaning or match a literal character).
The only character that will universally need escaping in .htaccess
is the space. Since the space is used as the delimiter between arguments. If the argument itself contains a space, then this must be escaped, otherwise the directive will simply fail to compile properly. If an argument contains a space then you can either backslash escape it, or surround the entire argument in double quotes. (If the argument is a regex then it may be easier/clearer to use the whitespace shorthand character class \s
instead.)
I found that dots don't need to be escaped - but for me it's irracional because they have meaning in "regex"
Well, exactly, you can't generalise and say that dots don't need to be escaped - that makes no sense. Whether a dot needs to be escaped at all depends on context and meaning. For example:
In an ordinary string argument (such as the
RewriteCond
TestString orRewriteRule
substitution) you do not need to escape the dot. The dot carries no special meaning here. Escaping the dot here causes no harm - it does nothing - but it can hamper readability, which is an important consideration.-
In a regex (such as the
RewriteCond
CondPattern orRewriteRule
pattern and any other Apache directive/argument that takes a regex):- If you wish to match any character (except newline) then you should not escape the dot.
- If you wish to match a literal dot, then you need to escape the dot to negate its special meaning.
- However, to match a literal dot inside a character class then you do not need to escape the dot. Since when used inside a regex character class, the dot carries no special meaning.
Note that Apache uses PCRE (Perl Compatible Regular Expressions) flavour of regex. The same escaping applies.
It has escaped all slashes which are not "beginning" ...
And this doesn't really make sense. (Unfortunately there are a lot of mod_rewrite/regex examples out there that are not strictly correct.)
The slash (/
) does not need to be escaped as it carries no special meaning in the regex (there are no slash delimiters). There is no harm in escaping it (except for readability), however, omitting the first slash and escaping the remaining looks like an error/typo. There is no reason why you would escape one and not the other.
Aside:
RewriteCond %{REQUEST_URI} /index.php\/component\/users\/\?task=registration.register [NC]
However, this whole condition looks wrong. Not because of the backslash escapes, but because it looks like you are seemingly trying to match the query string against the REQUEST_URI
server variable. The REQUEST_URI
server variable contains the URL-path only. This will only match if the question mark (?
) is URL-encoded as %3F
in the request (ie. there is no query string) - which would be unusual. Ordinarily, a condition like this will never match and the request is never blocked.
Why aren't both the dots escaped? It looks like they should be in this context. But only you know for sure whether they should be or not.
RewriteRule .* - [F,L]
The L
flag is not required (it is implied when used with the F
flag). The .*
regex is not optimal, however, the RewriteCond
directive should be removed and the URL-path should be tested in the RewriteRule
pattern instead.