I want to prevent direct access to the images in a certain directory, therefore I am trying to redirect the user to another page if (s)he tries to access the images directly.
here is the directory I want to prevent direct access:
www.example.com/assets/images/user-uploads/image.jpg
here is the directory I want to redirect to:
www.example.com/no-direct-access
and here is my
.htaccess
code:
RewriteEngine On
RewriteCond %{REQUEST_URI} \/assets\/images\/user-uploads\/(.) [NC]
RewriteRule ^(.*)$ index.php/no-direct-access [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
When I dial www.example.com/assets/images/user-uploads/image.jpg
it gives me 404 error.
Please help me with this.
CodePudding user response:
Direct as in I don't want anyone to view images lying in user-uploaded directory. if anyone dials to view any image in said directory using url like www.sitename.com/assets/images/user-uploads/image.jpg instead of opening the image file in browser they should be redirected to no-direct-access page. if the aforementioned image is part of any file (php or html) then it is okay to render the image.
The problem with your initial approach is that it will block every client-side request. Any images that are "part of any file (php or HTML)" will also be blocked.
To block only "direct requests" (ie. when the user types the URL directly into their browser) you can check the Referer
HTTP request header. This is empty on direct requests and set to the referring URL otherwise (ie. the page on which the link was clicked).
However, this is unreliable. Users can configure their browser to not send a Referer
header (so these users would be blocked). Search engine bots do not send a Referer
header (if that is a concern). And it is trivial for a mischievous user to fake the Referer
to gain access.
An additional "problem" with "redirecting" is that the user receives a 3xx HTTP response code indicating that the resource has "moved", not that is not accessible. However, with your "attempt" you are internally rewriting the request, so (if successful) this would return a 200 OK status (unless you manually override this).
It would be preferable to return 403 Forbidden and perhaps serve /no-direct-access
as the custom 403 error document.
For example, try the following instead:
ErrorDocument 403 /index.php/no-direct-access
RewriteEngine On
# Block direct access to the "user-uploads" directory
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?example\.com/
RewriteRule ^assets/images/user-uploads/ - [NC,F]
# CI front-controller
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php/$1 [L]
Where example.com
is your website's domain.