.htaccess is causing 403 on one link only - php

Bit of an odd one and I feel it must be answered but I can't seem to find it.
I have the following in my .htaccess file on a custom PHP site (NOT WORDPRESS):
Options +FollowSymlinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^(contact|gallery|links)$ $1.php [L]
I cannot work out why "gallery" only is giving me a 403.
example.com/links
example.com/contact
Both work as expected and go to the desired pages. However
example.com/gallery
Redirects to
example.com/gallery/
And throws the 403 Forbidden error
gallery.php is a page and can be accessed from the same URL
There's nothing on gallery.php to redirect or check a query string or compare the URI. I cannot understand it.
Really flying blind on .htaccess stuff (always have), so any help greatly appreciated. What am I doing wrong?!
Also, tested it on https://htaccess.madewithlove.com/ and it said my work was correct, so really don't understand what it's finding incorrect. Why does it think gallery is a subfolder, not a URL?
And I have JUST realised, I do actually have a gallery folder, so if anyone can tell me how to use the htaccess to access the page and not the folder, I'd greatly appreciate it! If it helps, there's a .htaccess in the gallery folder to prevent direct access to images:
Options -Indexes
Options -ExecCGI
# AddHandler cgi-script .php .php3 .php4 .phtml .pl .py .jsp .asp .htm .shtml .sh .cgi
<Files ^(*.jpeg|*.jpg)>
order deny,allow
deny from all
</Files>
<FilesMatch "\.(jpe?g)$">
order allow,deny
allow from all
</FilesMatch>
Would they be conflicting?

Since gallery is a physical directory, you will need to set DirectorySlash Off in order to prevent mod_dir appending the trailing slash via a 301 external redirect. (This redirect gets cached persistently by the browser, so you will need to clear your browser cache before continuing.)
Note, however, that when disabling the DirectorySlash, you must also ensure that Options -Indexes is also set to prevent mod_autoindex from generating directory listings when the trailing slash is omitted from a directory, since a DirectoryIndex document in that directory will no longer prevent the directory listing being generated. See the security warning under the DirectorySlash directive in the Apache Docs.
You may also need to set RewriteOptions AllowNoSlash to allow mod_rewrite to match directories that have no trailing slash.
You then need to modify your existing rule...
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^(contact|gallery|links)$ $1.php [L]
Remove the first two RewriteCond directives. They aren't required since you are wanting to rewrite 3 specific URLs. If any of the conditions fail then the rewrite does not occur.
If contact, gallery or links happen to exist as physical files (very unlikely) or directories (gallery is a directory it seems) then the rewrite does not occur.
Summary
DirectorySlash Off
Options +FollowSymlinks -Indexes
RewriteEngine On
RewriteOptions AllowNoSlash
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^(contact|gallery|links)$ $1.php [L]

Related

How to forward the HTTP_REFERER to a page from htaccess?

When someone hits my site root folder (www.myDomain.com) and the Index.php page gets it after that, how can I forward HTTP_REFERER to the Index.php page so I can record it?
I have this but No Joy.
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^mydomain.com [NC]
RewriteRule ^/?index.php?%{HTTP_REFERER}$ mydomain.com/ [L,R]
Thanks
Make sure apache mod_rewrite is enabled. Then redirect with:
<IfModule mod_rewrite.c>
# Make sure url's can be rewritten.
RewriteEngine on
# Redirect requests that are not files or directories to index.php.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]
</IfModule>
This is how most CMS's do it. this does mean if they write the direct path to a file they will see that file. So you will want to precede this with something like:
# Prevent direct access to these file types.
<FilesMatch "\.(sql|md|sh|scss|rb|conf|rc|tpl(\.php)?|lib(\.php)?|wig(\.php)?|pg(\.php)?|reg(\.php)?|db(\.php)?)$">
Require all denied
</FilesMatch>
This means that they can not access the file extensions listed above. You can replace the last few with just rc|php but I allow access to .php files not proceeded with .lib so I can do scripts protected by browser authentication for debugging and silver bullet database repairs.
You must also have something like this in your apache config that allows the .htaccess to be read in your sites directory.
<Directory "C:/Sites">
AllowOverride All
</Directory>

Require file extension in .htaccess

My website is redirecting mywebsite.com/news to mywebsite.com/news.php but I don't want it.
I need it to redirect mywebsite.com/news to mywebsite.com/index.php?param=news
I changed my .htaccess file and the file does work correctly for other words, like this:
mywebsite.com/hello redirects to: mywebsite.com/index.php?param=hello
I have a news.php file in my root folder, but I don't want mywebsite.com/news to redirect to mywebsite.com/news.php
I hope you understand what I mean...
This is my .htaccess file:
Options -Indexes
# pass the default character set
AddDefaultCharset utf-8
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^([\s\S]+)$ index.php?param=$1 [L,QSA,NC,NE]
What changes should I make to solve this?
Any helps, comments, suggestions is appreciated.
Change your Options line to:
Options +FollowSymLinks -MultiViews
The effect of MultiViews is as follows: if the server receives a
request for /some/dir/foo, if /some/dir has MultiViews enabled, and
/some/dir/foo does not exist, then the server reads the directory
looking for files named foo.*, and effectively fakes up a type map
which names all those files, assigning them the same media types and
content-encodings it would have if the client had asked for one of
them by name. It then chooses the best match to the client's
requirements.
https://httpd.apache.org/docs/current/content-negotiation.html
You also can remove .php extension with:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R=301,L]

.htaccess redirects to a template selection php file

How would I configure my .htaccess file if I want all requests to always load a core template selection file. I believe this could be good for a few reasons the first of which being security. Only if my php template selection code flags a file as safe for display will it display. Also, it allows me to build some interesting cms functionality like requiring a php metadata array in order to load the template file. How could I accomplish this?
Also, do you think it is practical to choose this method over others?
You can use this rule in your root .htaccess to make core/template.php your front controller:
RewriteEngine on
RewriteBase /
RewriteRule ^core/template\.php$ - [L,NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . core/template.php [L]
EDIT: If you want even real files to be routed to same controller use last rule as:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule !\.(jpe?g|ico|gif|bmp|png|tiff|css|js)$ core/template.php [L,NC]
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteRule ^(.*)$ /index.php
</IfModule>
Make sure that inside the httpd.conf this line isn't commented:
LoadModule rewrite_module modules/mod_rewrite.so
(It should be without the '#' at the beginning)
And this is my directory tag (I'm using wamp but it should be the same, and of course restart the apache server if you changed something there)
<Directory />
Options FollowSymLinks
AllowOverride All
Order deny,allow
Allow from all
</Directory>

Htaccess, Directory-Style not rewriting to query-style

I have a very basic htaccess, attempting to convert directory-style to query style.
i.e.
a. /public_html/main/folder1/folder2 ... etc
b. /public_html/main.php?1=folder1&1=folder2
No matter what regex I try, to matter what rewrite rule I try - I can't make any progress on this problem.
I've searched the web, many times so far. I've tried 10 different 'recommended' solutions found in other forums.
I don't know where else to look.
Here's my current htaccess:
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^public_html/([A-Za-z0-9]+)/([0-9]+)/?$ main.php?name=$1&page=$2 [NC]
Here's my httpd.conf Htaccess directives.
(Directory "/Users/admin/Sites")
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
Allow from all
(/Directory)
(Directory "/Users/admin/Sites/MFCS/V3/public_html/mfcs/public_html")
AllowOverride All
(/Directory)
I replaced the greater than / less than on the directory tags for this example.
the httpd.conf does have the proper tags in it.
Give this a try:
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^/main/(.*)/(.*)/?$ /main.php?name=$1&page=$2 [L]
This will redirect requests to:
http://www.example.com/main/folder1/folder2
To:
http://www.example.com/main.php?name=folder1&page=folder2
If this is not the outcome your looking for please provide a sample before and after. On another note did you make sure to enable mod_rewrite? I also removed the public_html from the URI because it's normally not visible to the public.

.htaccess works locally but not on server

I have apache & PHP on my local windows machine and my .htaccess rules work fine. I uploaded all my files to my Linux server and get different results. I have complete control of my Linux VPS. It isn't shared hosting or anything.
I created a file showme.php that all requests should go to. showme.php just outputs some $_SERVER variables just so I know it worked. But every request to the server gives me the 404 not found. The same request locally serves up showme.php like it should.
-Local example: http://localhost/somepage (I get the correct page rendered by showme.php)
-Server example: http://mydomain.com/somepage (I get a 404 message)
Here is my .htaccess file. I can't figure out why I get different results. Something with file permissions?
# AddType x-mapp-php5 .php
# AddHandler x-mapp-php5 .php
RewriteEngine on
Options +FollowSymlinks
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . showme.php [L]
ErrorDocument 404 /page-unavailable/
<files ~ "\.tpl$">
order deny,allow
allow from none
deny from all
</files>
If you use phpinfo() and do a search for mod_rewrite (usually under configuration) you will be able to tell if you have the ability to use RewriteRules. This is usually why you see IfModule wrapped around your rewrites:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . showme.php [L]
</IfModule>
The answer was that in my httpd.conf I needed AllowOverride All set in one certain place. It was there in certain directories but I guess not as default..

Categories