简体   繁体   中英

only allow PHP scripts to open urls like www.mydomain.com/topsecret/1/001.jpg

I run a web app where I store the users' uploaded files in a folder structure like:

www.mydomain.com/uploads/topsecret/1/001.jpg
www.mydomain.com/uploads/topsecret/1/002.jpg

Now, it's very easy to guess the urls for 003.jpg and 004.jpg ...

Therefore, I want to restrict user access to only www.mydomain.com/app/, and nothing else. Only my .php pages on localhost should be allowed to get to the top secret pdfs, like

show.php:
<? if ($isAdmin) {
    echo "<img src='http://www.mydomain.com/uploads/topsecret/1/001.jpg'/>";
 } ?>

Maybe there is a solution via .htaccess or via folder permissions. I know I could fix the problem via "headers" and "readfile", but that would cause a bit of refactoring now.

Thank you in advance, Matthias

This may be what you're looking for:

Place a .htaccess file containing this in the root of the folder you don't want the users to be able to access:

order deny,allow
allow from 127.0.0.1
deny from all

This will still allow access to the urls from a web browser on the web server, but attempting to access them from any other computer will result in a 403 error.

Some clarification: when you do an

echo "<img src='....'>";

PHP access doesn't matter (in fact it will work even if PHP doesn't have access to the file!). The first step is to realise, that it's the browser that makes the request for the image. So if the browser can access it, the user can access other images by guessing the name of the image. This would even work if you serve the images with readfile from PHP. That's why I wrote that you're trying to solve the problem the wrong way.

What you can do, is to obfuscate the image names (or the request variable you send to your PHP script). Eg: use a salt + MD5. That way users cannot guess the names.

in .htaccess use:

<FilesMatch "\.(engine|inc|jpg|po|sh|.*sql|theme|tpl(\.php)?|xtmpl|svn-base)$|^(code-style\.pl|Entries.*|Repository|Root|Tag|Template|all-wcprops|entries|format)$">
  Order allow,deny
</FilesMatch>

This will protect the files from direct access and then for example set your default index.php file to handle the $_GET request:

 RewriteBase /

  # Rewrite URLs of the form 'x' to the form 'index.php?q=x'.
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_URI} !=/favicon.ico
  RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]

You can embed your images encoded in base64 to look like this:

<img src="data:image/gif;base64,R0lGODlhUAAPAKIAAAsLav///88PD9WqsYmApmZmZtZfYmdakyH5BAQUAP8ALAAAAABQAA8AAAPb
WLrc/jDKSVe4OOvNu/9gqARDSRBHegyGMahqO4R0bQcjIQ8E4BMCQc930JluyGRmdAAcdiigMLVr
ApTYWy5FKM1IQe+Mp+L4rphz+qIOBAUYeCY4p2tGrJZeH9y79mZsawFoaIRxF3JyiYxuHiMGb5KT
kpFvZj4ZbYeCiXaOiKBwnxh4fnt9e3ktgZyHhrChinONs3cFAShFF2JhvCZlG5uchYNun5eedRxM
AF15XEFRXgZWWdciuM8GCmdSQ84lLQfY5R14wDB5Lyon4ubwS7jx9NcV9/j5+g4JADs=
" alt="British Blog Directory" width="80" height="15" />

The way you want to do it with <? if ($isAdmin) ... <? if ($isAdmin) ... - the user will still be able to see this piece of code if he's an admin -> he'll be able to guess the other filenames as well...

Here's a link: http://www.sweeting.org/mark/blog/2005/07/12/base64-encoded-images-embedded-in-html

Use readfile() in a script to show the user an image IF it is allowed. and block access to the actual files via .htaccess / chmoded correctly

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM