.htaccess RewriteCond – adding multiple exceptions - apache

My question is very simple, but I want to get it absolutely right the first try, because I'm working on a live website and bad things could happen if I blew this :)
So, as a part of a RewriteRule that forwards all my regular visitors to /myfolder/, there is an important line preventing the rule from being applied if you're already in that folder:
RewriteCond %{REQUEST_URI} !^/myfolder/
That works fine. What I want is to add my dev folder to that exception, so myself and my clients can access my development projects while all other URI's still get forwarded to /myfolder/
I'm guessing I need to modify the RewriteCond along the lines of:
RewriteCond %{REQUEST_URI} !^/myfolder/
(here I basically need 'OR' in the right syntax) !^/dev/
What's the correct syntax for this?

You can actually use this condition:
RewriteCond %{REQUEST_URI} !^/(myfolder|dev)/ [NC]

Related

Block direct access to .php files, less the index.php file and ajax.php file

been looking for your help, i found a method, but it is not as i wish. if someone can help me.
What I want is that nobody can enter a direct URL with .php
example when I enter my domain.com/buy/product.php, I want it to be forbidden,
I was looking for information here, I found this code that worked for me but in .htaccess
RewriteEngine On
RewriteCond %{THE_REQUEST} "^.+? [^?]+\.php(?:[?/# ]|$)" [NC]
RewriteRule !^index\.php$ - [F,L,NC]
it worked fine for me, but the problem that I in a directory /include/ajax.php , I use an ajax. and it gives me error to execute the ajax by browsing.
Now what I'm thinking how to make it work with that htaccess code that you can enter the index.php and /include/ajax.php, I tried all means but it does not work for me.
In another case if you know any code to add to my php or how to do for my version which is version 7.3, but without ruining my code.
Rather than giving you the answer straight out, I'm going to give you some hints so that you aren't copying code you don't understand.
Each RewriteRule has three parts:
the pattern to match against the URL sent by the browser
the URL to rewrite to
an optional set of flags for extra options
Before each rule, you can optionally have one or more RewriteCond lines which apply extra conditions to the rule; each has three parts:
a variable to match against
the pattern to match
an optional set of flags for extra options
The most important flag in this case is [F], short for [forbidden], which says "if the rule matches, instead of rewriting or redirecting, just server a 403 response.
You should very rarely need to test against %{THE_REQUEST}, which is a raw version of the request line from the browser; much more often, you want %{REQUEST_URI} and/or %{QUERY_STRING}.
The patterns in both RewriteRule and RewriteCond can be negated (i.e. "must not match this pattern") by starting them with !
So, if you wanted to return a 403 for all URLs ending ".bad", except for URLs ending "not.bad" or "only-a-little.bad", you could write this (note that $ is the way to say "must end here" in the regex patterns):
RewriteCond %{REQUEST_URI} !not.bad$
RewriteCond %{REQUEST_URI} !only-a-little.bad$
RewriteRule .bad$ - [F]
Hopefully it should be straight-forward enough to see how to adapt that to your requirements.
The full list of options and variables available is in the Apache manual.
After 2 days of looking for some code, I was able to read and understand.
study how htaccess works.
Thanks to the users who guided me, I found the solution.
Although my title is not quite correct.
My intention was always to block all .php that always the user wanted to enter directly by .PHP, I had found the code above, but it did not work with a specific file in the /include/ajax.php folder, exactly it was an ajax, I could not find solution.
exactly it was an Ajax, I could not find the solution to make it work.
Until I managed to solve this way.
RewriteEngine on
RewriteCond %{THE_REQUEST} ajax\.php [NC]
RewriteRule ^ - [NC,L]
RewriteCond %{THE_REQUEST} .+\.php [NC]
RewriteRule ^ - [F,L]
This causes all .php to be blocked, except the index.php and the /include/ajax.php file.
This is how it worked for me.
If I am right or wrong, can you give me some guidance.
I leave this in case someone might find it useful in the future.
I was always recommended to route my php, that I would forget about these problems.
I will keep it in mind as I move forward in the future, to route my php.

.htaccess vanity url not redirecting properly

I've got a blog subdirectory on my website (foo.com/blog), and I'm following a tutorial that offers a brief explanation of vanity urls.
Basically, I'm trying to get it so that when the user navigates to 'foo.com/blog/xyz' the 'xyz' variable (username) redirects the user to:
foo.com/blog/profile.php?username=xyz
but still displays as:
foo.com/blog/xyz
The code in the tutorial doesn't work, so I've been relying on code in the youtube comments under it:
RewriteBase /
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .* - [L]
RewriteRule ^(.*)$ http://www.foo.com/blog/profile.php?username=$1 [NC]
The problem is, when I try to navigate to 'foo.com/blog/xyz' it instead redirects to:
foo.com/blog/profile.php?username=blog/xyz
So obviously the username is being set to blog/xyz instead of xyz itself.
Likewise, if navigate to foo.com/xyz, it redirects to where it is supposed to go:
http://www.foo.com/blog/profile.php?username=xyz
But displays this url as it is instead of showing up as foo.com/blog/xyz (like how reddit shows up as reddit.com/u/username for users)
So it appears I have two problems:
1) I can't figure out how to make it so that it only does the rewrite when I navigate to foo.com/blog/xyz rather than foo.com/xyz (.htaccess is in public_html -- I tried moving it to public_html/blog but it didn't work)
2) I can't figure out how to get it to display as blog/xyz instead of blog/profile?php?username=xyz
I don't know much about apache, and I really just need to get this one piece of code right so I can continue bashing my head against the wall with the rest of the tutorial. Does anyone know what I'm doing wrong?
Well, you never mentioned in your rule set anything about how to treat that/bog part of the request path. Do it...
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?blog/(.*)$ /blog/profile.php?username=$1 [L]
I also cleaned up a few other issues with the code you posted which would prevent it from working as you claim at all.
And a general hint: you should always prefer to place such rules inside the http servers (virtual) host configuration instead of using dynamic configuration files (.htaccess style files). Those files are notoriously error prone, hard to debug and they really slow down the server. They are only provided as a last option for situations where you do not have control over the host configuration (read: really cheap hosting service providers) or if you have an application that relies on writing its own rewrite rules (which is an obvious security nightmare).

301 Redirect Whole Site Except One Folder, leave Add-on domains alone

I have a brainteaser and need help from people smarter than me. I have a shared hosting account. I'd like to 301 forward the root URL (say, domain.org) to a new URL. I also want one folder (/blog/) to be left alone (not forwarded). I was able to find an example of this here, and I put together this potential scenario for doing that:
RewriteCond %{REQUEST_URI} !^/blog/
RewriteRule ^(.*)$ http://newdomain.org/$1 [L,R=301]
I believe that this should be OK, but here's the trick: I have add-on domains in this hosting, and if I use the above, I'm pretty sure that I will forward every one of them to newdomain.org, not just domain.org. I did some testing using more specific text strings in the first spot following RewriteRule, but I can't seem to get the syntax without blowing up my site and getting a 500.
Any ideas would be greatly appreciated!
Thanks, Dave
Try adding another condition:
RewriteCond %{HTTP_HOST} ^domain\.org$ [NC]
RewriteCond %{REQUEST_URI} !^/blog/
RewriteRule ^(.*)$ http://newdomain.org/$1 [L,R=301]
Where domain.org is the domain that you want everything to be redirected to newdomain.org, except /blog/.

Shorten URLs with mod_rewrite

I am currently trying to make a URL shortener feature for one of my projects; what I want to do if a user visits the site with a URL that does not contain any slashes (for directories) or file extensions, it should redirect to a PHP script that will serve up the correct file. For example:
http://example.com/A123 would be rewritten as http://example.com/view.php?id=A123
but
http://example.com/A123/ would not be rewritten, and
http://example.com/A123.png would not be rewritten either. I have been messing with mod_rewrite for a few hours now and for the life of me I cannot get this to work...
With no way to identify the URI that needs to be shortened you need to exclude all other possibilities. This will likely require you to build a lengthy list of exclusions. Below is a starting point. Each of these conditions verifies the requesting URI does NOT match (signified by the !). When it doesn't match all conditions the rule is run.
RewriteCond %{REQUEST_URI} !^/view.php
RewriteCond %{REQUEST_URI} !.html$
RewriteCond %{REQUEST_URI} !/$
RewriteRule ^/(.*)$ http://example.com/view.php?id=$1 [QSA]
The above also requires you (as you have requested) to break a standard practice rule, which is to handle directory requests without a trailing slash. You are likely to come across other issues, as the rules above break your Apache server side directory rules.
Rethinking the logic. If you had some way to identify the URL that is to be shortened it would be much easier. For example 's', http://example.com/s/A123.
RewriteCond %{REQUEST_URI} ^/s/
RewriteRule ^/s/(.*)$ http://example.com/view.php?id=$1 [QSA]
I'm definitely no guru at this, but its similar to what I'm trying to accomplish (see my yet unanswered question)
However, if I understand correctly, this (untested) RewriteRule may work:
RewriteRule ^([^\.\/]*)$ view.php?id=$1 [L]
The magic part is the [^\.\/]* which says: 1 or more (*) instances of a charactor ([]) which is not ([^ ]) a period or a slash (\ escapes these charactors).
Like I said, I haven't tested this, nor am I an expert, but perhaps this will help.

Please help with this mod_rewrite issue

This current system in place needs to allow periods (.) optionally inside of the rewrite condition.
For example: /john.doe should work, since we allow periods in our user names.
However when I add . or \\. or [.] to the following rewrite rule, it either gets stuck in an endless loop, having to restart apache2. Amazingly, the behaviour has changed and I am not sure why. Now it just appends the new string to the existing URL.
For example: /john.doe will become /john.doe/?pg=user&username=john.doe
RewriteRule ^/([a-z0-9_]+)$ /?pg=user&username=$1 [NC,PT]
I am going crazy trying to fix this, please help!
This should work (I'm saying "should" as I do not know how your whole system is set up and what other redirects etc are in place -- I see you are using PT flag (maybe you are using aliases)):
RewriteCond %{REQUEST_URI} !^/index\.php
RewriteRule ^([a-z0-9_\.]+)$ /index.php?pg=user&username=$1 [NC,QSA,L]
OR
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([a-z0-9_\.]+)$ /index.php?pg=user&username=$1 [NC,QSA,L]
I have specified the script file directly -- it's much more easier to write a rule if you know how it works behind.