Make files not accessible via URL - .htaccess

How can I redirect via .htaccess file, that only the index.html can be accessed via URL.
I already got this:
RewriteEngine on
RewriteBase /
Options +FollowSymlinks
RewriteRule ^/?login/?$ /php/login.php [NC,R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.html [L,QSA]
It works fine if somebody types in for example "www.mypage.com/skd/lasnd"
but if somebody types in a file which exists on the webserver, e.g. "www.mypage.com/php/login.php", he will be redirected to that page. How to forbid that?
To be more exact: my JavaScript & PHP scripts should be still allowed to access to every file on my webserver.

These lines:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
are conditions "if REQUEST_FILENAME is NOT a file, if REQUEST_FILENAME is not a directory" and if both are met then RewriteRule is taking place. This is usually to allow "friendly urls" to work and at the same time to not rewrite any images, css etc. You can block access to files with many ways, but you have to take care to not block too much (like said images etc). The simplest approach would be to put your files in subdirectory and add another .htaccess file in that directory with line
Deny From All
This will make httpd reny any request to whatever is in that directory and subdirectories (unless another .htaccess overwrite these rules) while your scripts will be able to access them without a problem.
I strongly recommend do read mod_rewrite docs
EDIT
There's no "my javascript" and "their javascript". There's request and that's all you can tell for sure. You cannot tell which access yours and which is not. "i only want to deny request via typing in the browser adress line" - you can't tell that either. You theoretically could check REFERER, and if there's none set then assume it's direct hit, but REFERER comes from browser so it can be faked as well. And I personally block all REFERERS by default, so all my requests are w/o any REFERER even these not direct. You could try cookies, but again - these can be be grabbed by script and sent back too. The only real option is to Deny from all to these files and "tunel" them thru some sort of script (i.e. PHP) that would do i.e. file() on target file only if user authenticated himself previously using login and password. Any other attempts are broken from the start.

try the following
RewriteRule /.* http://www.new-domain.com/index.html

Related

htaccess rewrite stopped working properly

I have the following code block in my .htaccess file:
RewriteEngine on
RewriteCond %{REQUEST_URI} !^(.*)2021layout(.*)$
[other directories to omit, like assets and admin]
RewriteRule ^(.*) RESThandler.php
Basically I want certain directories to be processed normally, like 2021layout, while others use the REST handler. In the 2021layout directory, the member area is in the directory 2021layout/myaccount, and all css/js files are in 2021layout/assets/[whatever directory]. Both the assets and myaccount directories have permissions 0755.
On Friday, everything was working fine. Today, having changed nothing, pages in the 2021layout directory are working, and css and js files loaded by those pages are fine, but pages in the 2021layout/myaccount directory are trying to use the REST handler and getting redirected to my 404 page.
I have tried renaming both the 2021layout and myaccount directories, which didn't work. I have tried adding !^(.*)2021layout/myaccount(.*)$ as a RewriteCond, and that didn't work.
Why would this one specific directory suddenly stop obeying my htaccess instructions? Can I fix this?
Again, to reiterate: I didn't change anything to make this happen. It worked one day, and the next day it didn't, seemingly on its own.
EDIT: I have gotten the directory to work again by renaming the newly-created file settings.php to mysettings.php. So apparently the mere existence of settings.php within the directory was preventing it from loading correctly. Does anyone have any insight into this?
You may try this rule with THE_REQUEST:
RewriteCond %{THE_REQUEST} !\s/2021layout/ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ RESThandler.php [L]
THE_REQUEST variable represents original request received by Apache from your browser and it doesn't get overwritten after execution of other rewrite directives. Example value of this variable is GET /index.php?id=123 HTTP/1.1
Make sure to clear your browser cache before testing this change.
So apparently the mere existence of settings.php within the directory was preventing it from loading correctly. Does anyone have any insight into this
I am guessing that you have option MultiViews turned on in your Apache config. To turn it off use this directive at top of your .htaccess:
Option -MultiViews
Option MultiViews (see http://httpd.apache.org/docs/2.4/content-negotiation.html) is used by Apache's content negotiation module that runs before mod_rewrite and makes Apache server match extensions of files. So if /file is the URL then Apache will serve /file.html.

How to make webpage act like a subdirectory with htaccess

I'm building a website which has a profile page for each user.
I'd like the profile pages to be accessed through visiting a web address, eg:
example.com/profile/username
Obviously it would be impractical to create a new PHP file for each registered user, and so what I'm trying to do is redirect traffic from example.com/profile/(whatever) to example.com/profile, where I can then interrogate the URL and load the correct profile from a database.
However, I'm really struggling to work out how to do this with .htaccess. I've tried all sorts of redirects, etc, but can't seem to get it to work. Can anyone point me in the right direction?
The only other thing I've got in my .htaccess file at the moment is the below to remove .php from URLs:
# Remove .php
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
Any advice gratefully appreciated!
redirect traffic from example.com/profile/(whatever) to example.com/profile
Note that you should internally rewrite directly to the file that handles the request, which I assume is /profile.php, rather than relying on another rewrite to later append the extension. I assume that code in /profile.php already processes the request as necessary.
I will also assume that "username" can consist only of the characters a-z, A-Z, 0-9, _ (underscore) and - (hyphen). Generally, you want to be as specific as possible.
Try something like the following:
RewriteEngine On
# Disable MultiViews to avoid conflicts with mod_negotiation
# (Since you are using "extensionless URLs")
Options -MultiViews
# Handle requests for `/profile/<username>
RewriteRule ^profile/([\w-]+)$ profile.php [L]
# Append the ".php" extension to any request that does not end in a file extension
RewriteRule ^([^.]+)$ $1.php [L]
Whilst the comment in your code states "Remove .php". The code actually appends the file extension to URLs that don't have one.
This currently only works for files in the document root (as per your original code), eg. /foo. It won't do anything with /foo/bar for instance.
The condition that checks against the file system (ie. RewriteCond %{REQUEST_FILENAME} !-f) was not required in your existing code, unless you have actual files that don't contain a file extension? I'm also assuming you do not need to access filesystem directories directly (as per your original code).
There is no need to escape literal dots when used inside a character class.

.htaccess RewriteRule not redirecting from real folder

I'm still a bit fuzzy on the working of .htaccess, and I've looked around but I can't find anything to help this specific issue.
EDIT: I realize there are other questions that seem like they cover this issue, but I checked some and they didn't seem to offer any help I could understand, and I didn't want to hijack them with my own issues.
This is what I have:
Options +FollowSymLinks
#RewriteBase /
RewriteEngine on
RewriteRule /mp3/(.*) http://old.domain.com/mp3/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]*)$ /index.php?p=$1 [L]
As you can see from the last line, the string typed after the server name is actually a URL parameter and depending on that parameter, different content is pulled from the database and that page is displayed on the site.
The problem I'm having is that the client has a content page called "podcast", so they would go to site.com/podcast which should quietly redirect to site.com/index.php?=podcast and load the content for that page. Unfortunately, the client also has a real site.com/podcast/ folder on their server. Because of this, the rewrite is ignored and the browser attempts to load that folder. It either shows a file listing or a forbidden error if I disable the listing.
After some research (I'm still new to htaccess), I learned that the two lines prior disable the rewrite if the path points to an actual file or folder. Unfortunately, commenting out the one with !-d doesn't seem to have any effect, and commenting out both gives me a server error.
Admittedly, part of the problem here was lack of foresight. URL rewrites should have been planned before everything else was put together, but it wasn't until the site was basically completed that I was notified that the client wants "Friendly URLs" that don't include the ?p= part. Regardless, perhaps there is a way to fix this.
Is there some .htaccess trickery I can use that will force the rewrite even if the URL entered points to a folder (not a specific file) that actually exists? As stated before, removing the !-d doesn't seem to help, although I'm not sure why. Perhaps I misunderstand its purpose.
Thank you for any help, and please be lenient with me if I overlooked something obvious. This is an issue presenting itself on the client's live site right now so I feel a little rushed in solving it. Thanks again.
OH YEAH, and the solution can't be specific to /podcast. The way the client's site is set up, when they want to create a new subpage for the site, a new name is saved for that content based on their title for the page and it is possible (unlikely, but still possible) that another page can be created with a name that matches an existing folder on the server.
Here is a note from mod_rewrite documentation:
By default, mod_rewrite will ignore URLs that map to a directory on
disk but lack a trailing slash, in the expectation that the mod_dir
module will issue the client with a redirect to the canonical URL with
a trailing slash.
This explains why mod_rewrite ignores the URL /podcast. I would suggest that you rename physical directories so that do do not (accidentally) match article names.
Another option would be to disable the DirectorySlash setting. This will prevent Apache from redirecting /podcast to /podcast/.
DirectorySlash Off
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]*)$ /index.php?p=$1 [L]
Be warned that disabling this setting has side effects. Read through the documentation first.
Change the following line of code:
RewriteRule ^([^/]*)$ /index.php?p=$1 [L]
to
RewriteRule ^(podcast([^?]*)) index.php?p=$1 [L,NC]

PHP url # split

I have a .htaccess file with those contents:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ([^/\.]+)$ index.php?string=$1&match=all [L]
So when I type: domain.com/test
the page redirects to domain.com/index.php?string=test&match=all
But if I want to reach this page: domain.com/test#sub1
the page redirects to domain.com/index.php?string=test&match=all
instead of domain.com/index.php?string=test#sub1&match=all
How do I proceed?
Anchors/hashes are only used by the browser. The server won't see requests for those, because such a request would be invalid. (There is no "test#sub1" file, only a "test" file.) It has no way of knowing you're just wanting to access an anchor and not trying to access a file that doesn't exist, so such information is not passed to the web server.
EDIT: Also, redirecting everything through a single php file just seems like malpractice to me. Maybe there's something special going on here that makes it a reputable approach though.

how to do hide all file extentions?

Right now im using .htaccess to hide .htm extentions:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.htm [NC,L]
But i also have php in my site (not to mention javascripts and images, etc..). So how do i change my htaccess to hide all file extentions? (or at least just .htm and .php)
edit: i dont know if it matters, but im on a linux server.
edit2: i tried some of the things i saw on the web and none is worked properly..
Options +MultiViews
should do that trick (replacing your current script). See documentation
(You might need to add some rewrite rules to redirect urls with extension to ones without, to prevent multiple urls pointing to the same resource)

Resources