0

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.

4
  • "I tried all means" - please include what you've tried. To allow /include/ajax.php as well is just a minor change to what you already have. So, maybe there are other issues? (Where did you get that code from? # will never appear in the request that reaches your server.)
    – MrWhite
    Commented Mar 7, 2022 at 19:07
  • Please edit your question to include the additional information and retain the formatting. That code looks entirely invalid, but that may be due in part to the incorrect formatting (which omits certain characters due to conflicts with the markdown syntax).
    – MrWhite
    Commented Mar 7, 2022 at 19:20
  • What do you URLs look like? How are these routed? Assuming your normal URLs are not of the form <something>.php? Please include the contents of you existing .htaccess file.
    – MrWhite
    Commented Mar 7, 2022 at 19:22
  • I am not understanding well. But my index.php is in the main folder. When I add the htaccess code, I login to my website without problems. But it blocks me an ajax, that this is hosted in /include/ajax.php Now what I am trying to do is that the index.php works with the /include/ajax.php, that the visitor when he enters by domain.com works. but in my case it is not happening this way.
    – Razyit
    Commented Mar 7, 2022 at 19:30

2 Answers 2

2

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; and . means "any character", but \. matches an actual .):

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.

3
  • Thanks, I understand what you mean, in my case my only goal is to block any user who enters directly by .php, but I can not make it work, I found codes that blocks the .php but when I enter my domain .com/, I get the 403 warning. So I started to look for some extra solution. in this case I found that code that I mentioned at the beginning. To be precise, is there any code that works as I mentioned now? That blocks all .php to the user that enters directly, but that works to those who enter by domain domain .com/
    – Razyit
    Commented Mar 7, 2022 at 19:10
  • @Razyit Users don't "enter" a site via any particular route. The browser makes requests to the server, and the server responds. Every request is separate. You can handle different URLs differently, and you can serve content based on cookies (e.g. by giving them a session ID when they log in) but you can't tell how they loaded a page.
    – IMSoP
    Commented Mar 7, 2022 at 19:12
  • I understand, I just added. RewriteCond %{REQUEST_URI} !index.php$ RewriteCond %{REQUEST_URI} !ajax-details.php$ RewriteRule .php$ - [F] I get the whole page in 403.
    – Razyit
    Commented Mar 7, 2022 at 19:22
1

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.

3
  • I see how this works, but it can be tidied up easily.Firstly, as I already mentioned, you rarely want to test "THE_REQUEST", and "REQUEST_URI" should work just fine here. Secondly, you can make it into one rule: a condition of !ajax\.php ("not ajax.php") and then a rule with .+\.php instead of just ^
    – IMSoP
    Commented Mar 12, 2022 at 10:36
  • Also, beware that patterns can match anywhere in the URL unless anchored with ^ and $ so this also allows a request for "my_awesome_ajax.php" and even (because you've tested THE_REQUEST instead of REQUEST_URI) "something_else.php?haha=ajax.php"
    – IMSoP
    Commented Mar 12, 2022 at 10:39
  • I had to log in to upvote you, it was really helpful in combination with my Yii2 Urlmanager. I searched for a long time for a solution Commented May 3 at 19:20

Not the answer you're looking for? Browse other questions tagged or ask your own question.