Search code examples
.htaccesscodeignitermod-rewrite

Codeigniter htaccess not redirecting to localhost/index.php/no-direct-access


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.


Solution

  • 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.