.htaccess deny dot-files but allow letsencrypt - regex

My goal is to deny access to all dot-files e.g .htaccess, .env and send back a 404, but allow the letsencrypt-folder .well-known to be accessed
RewriteEngine On
RewriteRule "(^|/)\.(?!well-known)" - [F]
RedirectMatch 404 /\..*$
Any hint on how to achieve this is highly appreciated
Best endo

Try the following instead:
RewriteEngine On
RewriteRule (?:^|/)\.[^/]+$ - [R=404]
This will serve a 404 for any file (or rather, last URL-path segment) that starts with a dot. But it will permit .well-known/ - since this is a directory and so is also suffixed by at least a slash + filename.
UPDATE: Modified regex so that it matches the dot at the start of the last path-segment, rather than anywhere in the last path-segment!
Note that the F flag responds with a 403 Forbidden, not a 404 as requested.
Alternatively, you can use a <Files> (or <FilesMatch>) container, which only matches "files". For example:
<Files ".*">
# 404 Not Found
Redirect 404 /
# OR... 403 Forbidden
#Require all denied
</Files>
Although this does also block a request for /.well-known (no trailing slash) - although that's not strictly a valid request anyway.

Related

htaccess redirectMatch all files of a type except a certain one

Say I have a web folder with:
/index.html
/assets/css/styles.css
/assets/images/logo.png
/something.html
/holdingpage.html
/finale.html
/folder/somefile.html
/else.html
/PDFs/something.pdf
I want to put in place an htaccess RedirectMatch for this to "catch" all the files that are html files except the finale.html and redirect to there.
What I have so far is:
RedirectMatch 302 ".*/$" "/finale.html"
Which correctly catches all folder without filenames (indexes).
What I need is to catch all the html but not that destination one.
RedirectMatch 302 ".*(\.html)$" "/finale.html" # This loops obviously.
So I tried to be more specific;
RedirectMatch 302 ".*!(finale.html)$" "/finale.html"
RedirectMatch 302 ".*!(finale\.html)$" "/finale.html"
But this doesn't catch other files. Also by the looks of it I'd expect this to also catch assets and images.
I am trying to find a redirectMatch that finds every .html page that is NOT finale.html and redirect it to that page.
IT should be a redirectMatch and NOT a rewriteCond / rewriteRule. The user needs to see they're being redirected.
I imagine I want something like:
RedirectMatch 302 ".*((\.html) BUT NOT (finale.html))$" "/finale.html"
I have read the Apache Documentation but this doesn't really elaborate on this concept very much.
You can use a negative lookahead to match all .html files except for /finale.html (in the document root).
For example:
RedirectMatch 302 (?!^/finale\.html$)^/.+\.html$ /finale.html
IT should be a redirectMatch and NOT a rewriteCond / rewriteRule. The user needs to see they're being redirected.
I'm not sure of the logic here. mod_rewrite can produce external redirects just the same as RedirectMatch and in fact, you should probably be using mod_rewrite here if you have existing mod_rewrite directives (primarily to avoid unexpected conflicts).
With mod_rewrite, you can do it similar to above with a negative lookahead. For example:
RewriteEngine On
RewriteRule (?!^finale\.html$)^.+\.html$ /finale.html [R=302,L]
Or, use an additional condition to make an exception for finale.html, instead of using a negative lookahead. For example:
RewriteCond %{REQUEST_URI} !^/finale\.html$
RewriteRule \.html$ /finale.html [R=302,L]
Which is arguably easier to read and possibly more efficient (the regex at least).
This matches all URLs that end in .html, except for /finale.html (exactly) and externally 302 redirects to /finale.html.
Aside:
RedirectMatch 302 ".*!(finale.html)$" "/finale.html"
The ! in the middle of the regex is a literal character here. The ! prefix-operator is a feature of mod_rewrite. (It is a prefix-operator, not part of the regex syntax itself.

Rewrite URL on .htaccess

I have urls like www.example.com/de/something and I need to redirect to www.example.com everything that starts with /de/.
At the moment I have done this
redirect 301 /de http://example.com
and it redirect all links but just removing /de part and result is www.example.com/something.
How to fix this?
Thanks
redirect directive matchs rest of the uri and appends it to the target, you can use RedirectMatch to redirect a specific uri
redirectMatch 301 ^/de/? http://example.com
If you want /de/ in the target you should have specified so, becasue Redirect will include in the target everything "after" what you have matched.
For a different virtualhost as the destination you want this:
Redirect 301 /de/ http://example.com/de/
or
Redirect 301 /de http://example.com/de
If what you want is redirect inside the same virtualhost /de to /, then use a negative lookahead.
RedirectMatch ^(?!de) http://example.com/
If the context is .htaccess, for virtualhost It would be:
RedirectMatch ^/(?!de) http://example.com/
Note: I use /de/ originally because that's what you describe in your question, and also I match slashes in the target. Both source and target without slashes would be fine too for cases like /desomething or /de/something. In any case, always match slashes or the lack of them.
Note2: Do not use .htaccess to redirect unless you are not the admin of the site. It just complicates things and adds unnecessary overhead since the file/s need to be checked a number of times per hit.

Apache LocationMatch regex ignores duplicate slashes

I'm having a strange behaviour with Apache's LocationMatch directive when there are extra slashes at the beginning of the URL. According to the Apache docs if I'm reading it right this should work:
<LocationMatch ^/appcontext/(a|b)>
SetHandler weblogic-handler
WebLogicCluster apphost01:xxxx,apphost02:xxxx
WLProxySSL ON
</LocationMatch>
However if I type the following URL it is also being forwarded to the backend hosts:
https:// <hostname:port> ////////appcontext/a/
In the Apache docs it clearly states that it should apply the directive only for /appcontext/a/, unless I'm missing something with the regex or there is some issue with the mod_wl plug-in
http://httpd.apache.org/docs/2.2/mod/core.html
"For example, <LocationMatch ^/abc> would match the request URL /abc but not the request URL //abc"
Does anyone have any suggestion to achieve this?
Yes Apache does collapse extra slashes in rewrite rule. You can use THE_REQUEST variable to match and remove extra slashes. Place this in root .htaccess:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^(.*?)//+(.*)$
RewriteRule ^ %1/%2 [R=302,L,NE]

Regular expression in htaccess file incorrectly matching root dir

I have the following .htaccess file on our xxx.yyy.edu site, in the root.
<FilesMatch "(.+)\.php">
AuthType shibboleth
ShibRequestSetting requireSession 1
ShibUseHeaders On
Require valid-user
ShibRequestSetting redirectToSSL 443
</FilesMatch>
This should only match files that end in .php, and match all files that end in .php, then force authentication. That part of it appears to work fine.
However, it also matches the root url, http://xxx.yyy.edu and http://xxx.yyy.edu/. Which isn’t a good thing, since it is forcing the root of the site to be authenticated.
It does not match xxx.yyy.edu/index.htm, or any other url that has anything after the domain name, like xxx.yyy.edu/students.htm or even xxx.yyy.edu/x
I’ve tested it in www.regexr.com, and it does not match the root url there.
Any thoughts/suggestions appreciated.
You are getting authentication dialog because on your landing page default page is set to index.php.
Have this FilesMatch with negative lookahead to avoid index.php from authentication:
<FilesMatch "^(?!index\.php$).+?\.php$">
AuthType shibboleth
ShibRequestSetting requireSession 1
ShibUseHeaders On
Require valid-user
ShibRequestSetting redirectToSSL 443
</FilesMatch>
Sounds like perhaps it is matching the newline with the "dot" (a la XRegExp). Try something like \w+:[\d\w\s\./]+\.php.

making apache and django add a trailing slash

My /train directory is aliased to a script in httpd.conf by:
WSGIScriptAlias /train /some-path/../django.wsgi
And it works well, except for one problem. If a user goes to /train (with no trailing slash) it will not redirect him to /train/, but will just give him the right page. This is a problem because this way the relative links on this page lead to the wrong place when no trailing slash was used to access it.
How can this be worked out?
Thanks.
I'm using something like this for redirecting /train to /train/, what I do is redirecting all the URL than doesn't end with / to /train/.
<Location "/train">
Order deny,allow
Allow from all
RewriteEngine on
RewriteRule !^.*/$ /train/ [R]
</Location>
WSGIScriptAlias /train /some-path/../django.wsgi
If you just need to redirect from /train to /train/ and not from every subdirectory without a trailing slash, then there's a simpler solution using the RedirectMatch directive:
RedirectMatch ^/train$ /train/
Set your urlconf to accept train/ as valid instead, then make train lead to a generic redirect to /train/.