1

I have a PHP-Project, where I am redirecting every URL to index.php. But the files in uploads folder (.png, .pdf, etc.) can be accessed directly. Is there a way to prevent this and also redirect URLs like https://example.com/uploads/asdf.pdf to index.php.

This is my .htaccess file:

AddType application/x-httpd-php .html
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [L,QSA]
RewriteRule ^([^\.]+)$ $1.php [NC,L]

Made some changes on the .htaccess file, but did not help.

MrWhite
  • 43,179
  • 8
  • 60
  • 84
ibo_dc
  • 33
  • 4
  • 2
    Do you know what your line `RewriteCond %{REQUEST_FILENAME} !-f` actually does? Now consider that those PDF files are actual files in your file system, obviously. So what will be the effect of that line? – arkascha Aug 07 '23 at 19:03
  • I get it, but it has to load the JS and CSS files and when I delete the line of code, it is not loading those files. So I need something, which loads the css and js files, but not pdf's. – ibo_dc Aug 08 '23 at 14:06
  • Usually one does not allow direct access to files _at all_ . Instead all requests are routed through a script, also those requesting physical files like your documents. That allows to implement flexible access controls. And keeps things like actual storage path away from the client where it does not belong. – arkascha Aug 08 '23 at 17:50

1 Answers1

1
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [L,QSA]

To rewrite all requests that do not map to physical files OR that map to .pdf files in the /uploads directory to index.php then you can basically just add an additional OR'd condition to the above rule.

For example:

RewriteCond %{REQUEST_URI} ^/uploads/[^/]+\.pdf$ [OR]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]

So, the above states that any request of the form /uploads/<file>.pdf (regardless of whether that .pdf file exists or not) OR that does not map to a physical is rewritten to index.php.

If you wish to rewrite everything in the /uploads directory through index.php then simply change the regex from ^/uploads/[^/]+\.pdf$ to ^/uploads/.

I also simplified (and made more efficient) the regex in the RewriteRule directive (since you don't need to match and capture everything) and the QSA flag was redundant here.


UPDATE:

How is it possible with files, which are in a subfolder of the uploads folder?

You can tweak the regex in the preceding condition (RewriteCond directive). For example...

  • A specific subfolder of the uploads folder:

    RewriteCond %{REQUEST_URI} ^/uploads/subfolder/[^/]+\.pdf$ [OR]
    :
    
  • Any subfolder of the uploads folder:

    RewriteCond %{REQUEST_URI} ^/uploads/[^/]+/[^/]+\.pdf$ [OR]
    :
    
  • Any .pdf file under the /uploads folder (including any subfolder):

    RewriteCond %{REQUEST_URI} ^/uploads/.+\.pdf$ [OR]
    :
    

See the following question for details on regular expressions (regex):
Reference - What does this regex mean?

MrWhite
  • 43,179
  • 8
  • 60
  • 84
  • Yes it works for the files in the uploads folder! Thanks a lot. How is it possible with files, which are in a subfolder of the uploads folder? – ibo_dc Aug 08 '23 at 20:17
  • 1
    @ibo_dc I've updated my answer with some examples. – MrWhite Aug 08 '23 at 22:18