restrict browsing to some resources - apache

I have a website(angular) hosted on a apache server and i want to deny access to some path for security purposes
The website is currently organized like this
index.html
polyfills.js
scripts.js
main.js
package.json
styles.css
assets
configuration
configuration.json
styles
images
I want to rescrict url access to configuration.json , package.json
I tried to add a rule in my .htaccess for testing
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /myapp/
RewriteRule ^index.html$ -[L]
RewriteRule ^refresh.html$ -[L]
# added rule
RewriteRule (^|/)configuration.json(/|$) - [F]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.html [L]
</IfModule>
It correctly forbids the usage of path /myapp/assets/configuration/configuration.json but it prevents also other resources (like main.js and polyfills.js) to use the configuration file which i dont' want because i can't access to the website anymore due to errors in browser console
I want only forbid direct url access
Browser console log
polyfilles.js : GET http://xxxx/myapp/assets/configuration/configuration.json 403 (Forbidden)
main.js : ERROR () => new Error('Error retrieving configuration file. ' + error)
How can i avoid this ?
Thank you very much

You can't block a resource from client access if it needs to be accessed from the client (using JavaScript). So, what you are asking is not really possible without restricting all client access (eg. user/password authentication), but then any authenticated users can still access these files.
You could prevent "casual" direct access by customising the client-side request with a custom HTTP request header and check for this header in .htaccess and block otherwise. However, this depends on how these files are currently being called as it will require an update to your JS code.
For example, when requesting package.json or configuration.json you also send an HTTP request header like X-Custom-Header: some-value.
In .htaccess you can block requests that don't have this header (or it is not the correct value). For example:
RewriteCond %{HTTP:X-Custom-Header} !^some-value$
RewriteRule (^|/)(package|configuration)\.json$ - [F]
This only prevents casual direct access, ie. someone types the URL directly into the browser address bar. Since the file is still downloaded to the browser, the user can still read the file in the browser (dev tools). The header can also be easily faked if someone is so inclined. So, this doesn't provide any real security.
Instead of sending a custom HTTP request header, you could perhaps check the Referer header (if this is being set for such requests). However, this is less reliable as the browser can be configured not to send the Referer header. And again, this is easily faked.

Related

Specify to load index.html file for every request in apache config file

I have a React application hosted on my server and I need to always load index.html file for every request users make.
Let's say that I have a website that has the address xyz.com, and the root directory contains the React build files, including this index.html file. There are many routes that users can specify to access to certain parts of the website, for example to register on the website they can access xyz.com/register. So, what I want to accomplish is instruct server to always serve this index.html every time users access my site, even though they are visiting different routes of the website.
So I'm assuming that this is something that I can set up in the .conf file for the website, and if it is, can you please let me know how I can achieve it?
You can use the below rewrite rule.
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/index.html$
RewriteRule .* /index.html [L,R=302]

.htaccess redirects if the condition doe not match/ negative condition

I am modifying the .htaccess file of a legacy PHP web application. I am not familiar with apache .htaccess syntax. I found this tutorial. What I am trying to do is that I am trying to redirect all the requests to a URL/ path if the request URL is not a specific URL/ path. For example, all the requests to the website will be redirected to localhost/my-custom-page unless the request URL is localhost/my-custom-page.
I know how to redirect mapping 1 to 1 as follows:
RewriteEngine on
RewriteRule ^my-old-url.html$ /my-new-url.html [R=301,L]
But, what I am trying to do is that redirecting all the requests to the specific page unless the request is to that page. Even the home page will be redirected to that page. How can I do that?
When I tried the following solution
RewriteEngine on
RewriteCond %{REQUEST_URI} !/my-new-url\.html
RewriteRule ^ /my-new-url.html [R=301]
I get the error
I want to check using OR condition as well. For example, if the path is not path-one or path-two, redirect all the requests to path-one.
Your question is a bit vague, due to your wording. But I assume this is what you are actually looking for:
RewriteEngine on
RewriteCond %{REQUEST_URI} !/my-new-url\.html
RewriteRule ^ /my-new-url.html [R=301]
In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup.
It is a good idea to start out with a 302 temporary redirection and only change that to a 301 permanent redirection later, once you are certain everything is correctly set up. That prevents caching issues while trying things out...
This rule will work likewise in the http servers host configuration or inside a dynamic configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a dynamic configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.
And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using dynamic configuration files (".htaccess"). Those dynamic configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).
RewriteCond %{REQUEST_URI} !/my-new-url\.html
RewriteRule ^ /my-new-url.html [R=301]
There are a few potential issues with this, particularly since you hint in a comment that you are perhaps using a front-controller to "route" the URL.
This redirect satisfies the conditions outlined in the question, but does assume that you have no other rewrites, have an essentially "static site" and are not linking to any static resources.
You are missing an L (last) flag, so processing will continue through the file and possibly be rewritten if you have later rewrites.
If you are rewriting the URL to a front-controller in order to route the URL (as you suggest in comments) then this redirect will break, as it will redirect away from the front-controller. You need to only redirect direct requests, ie. when the REDIRECT_STATUS environment variable is empty.
If you are linking to any static resources in the same file space then these will also be redirected. You need to create an exception for any static resources you are using, either by file extension (eg. (css|js|jpg|png)) or by location (eg. /static).
So, try the following instead:
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} !\.(js|css|jpg|png)$
RewriteRule !^my-custom-url$ /my-custom-url [R=302,L]
You don't need a separate condition to implement the exception for the URL you are redirecting to. It is more efficient to do this directly in the RewriteRule pattern.
The first condition ensures we are only redirecting direct requests and not rewritten requests to your front-controller.
The second condition avoids any static resources also being redirected. You could alternatively check the filesystem path if all your resources are stored under a common root. Or, as a last resort, implement filesystem checks (ie. RewriteCond %{REQUEST_FILENAME} !-f) if your static resources are too varied - but note that this is less efficient.
You will need to clear your browser cache before testing, since any earlier (erroneous) 301s are cached persistently by the browser.

htaccess redirect URI to parent directory

I have a website hosted in /var/www/thesite (apache server), it's a Symfony2 website so inside this folder I have a web folder to which my virtual host is pointing.
So my virtualhost is www.mysite.com -> /var/www/thesite/web
In this web folder I have a .htaccess to format URL nicely.
Now, I've added an API in /var/www/thesite/api, the API is implemented using Silex.
I want to redirect all request http://www.mysite.com/api to this new framework.
So I've added in /var/www/thesite/web/.htaccess
RewriteCond %{REQUEST_URI} ^/api
RewriteRule ^api(.*)$ ../api/web/index.php [NC,QSA,L]
But I get:
Bad Request
Your browser sent a request that this server could not understand.
I'm not sure if I can access parent folder in the .htaccess. I don't want to change my virtualhost target directory to avoid security breach.
How can I solve this issue?
You can't route a request to outside of the site's document root, which is /var/www/thesite/web. So you can't access /var/www/thesite/ or /var/www/thesite/api from inside the /var/www/thesite/web directory. The 400 Bad request is because of the ../api/ bit of your rule's target.
Something you can try doing is just using php to include/require the api's index.php:
RewriteRule ^api/(.*)$ /index_api.php [L]
And in the index_api.php you can include or require the "../api/web/index.php" file.

Short-urls without index files?

I'm wondering how urls like these are generated: http://www.example.com/Xj7hF
This is a practice I have seen used by many url shorteners as well as other websites that supposedly don't want to display data in the url in a parameter format.
Surely they can't be placing index files in the folder destination /Xj7hF etc with a redirect to the actual url, so I'm wondering how this is done.
Any help would be very appreciated!
(I'm running on a Linux server with Apache).
Different web development frameworks and web servers do it in different ways, but, the most common is probably using mod_rewrite with apache. Basically, the web server sends the request to a dynamic scripting language (eg. PHP) rewritten in such a way that the script doesn't need to know what the original request URI looked like and the client browser doesn't need to know what script actually processed the request.
For example, You will often see:
http://something.com/123/
This is a request for /123 which Apache may rewrite as a request to /my_script.php?id=123 based on how the user configured mod_rewrite.
(.htaccess example)
# if the request is for a file or directory that
# does not actually exist, serve index.php
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?url=$1
This is known as URL rewriting and is usually performed via proper configuration of the webserver. StackOverflow has several tags for this, so you should be able to find more information there.

How to prevent Apache / mod_rewrite from treating path as file with same name

I'm using WAMP Server, mostly configured as-is out of the box. I'm having trouble getting mod_rewrite to behave as expected locally (everything works fine on a production server).
I have a PHP file located at:
/ajax/graphs/get-graph.php
The way this file is normally invoked is via a bootstrap file loaded by
/index.php
I have a .htaccess file at the root with the following rules:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php [L]
So, basically, when my app requests via AJAX a call to /ajax/graphs/get-graph/it should be directed to /index.php.
The problem is, Apache/mod_rewrite sees the request path and loads /ajax/graphs/get-graph.php directly.
How do I prevent Apache from assuming that /ajax/graphs/get-graph/ is a valid file because a php file of the same name exists at that location?
It sounds like you've fallen into the trap of content negotiation ;-) As explained in the Apache documentation, there is an option called MultiViews which, when enabled, causes Apache to basically convert nonexistent directory names into their corresponding filenames.
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...
The intent is that you can have several versions of a file in different formats or languages, like
/some/dir
- foo.en.gif
- foo.en.png
- foo.en.jpg
- foo.fr.gif
- foo.fr.png
- foo.fr.jpg
and Apache will choose the best one based on the preferences provided by the browser.
To fix it, all you should need to do is add the directive
Options -MultiViews
in a <Directory> or <Location> block corresponding to /ajax/graphs. Or, if you don't have access to the main server configuration, you can put it in /ajax/graphs/.htaccess.