Jump to content

Archived

This topic is now archived and is closed to further replies.

bltesar

protecting files/folders

Recommended Posts

I have a site that allows access to registered users only with authentication via PHP/MySQl.  It works just fine, and only authorized users can access the site beyond the login page; however, anyone can easily access images on the site, provided they know the names of the images, by navigating to the address of the images. 

How can I protect the images on this site from public access?

Share this post


Link to post
Share on other sites
Put this in the image folder ok.


index.php

[code]
<?php
header("location: index.php");
?>
[/code]

Share this post


Link to post
Share on other sites
Yes, but what if someone guesses the name of one of my images, which is actually a realistic possibility. 

The website I created is for a real estate company.  Some of the photos are displayed on the public website, others are not.  The photos are all named in the same way, e.g. floorplan_00023, so anyone could try different versions of that and access all the photos. 

I could just put all the private photos in a password protected folder, but there are other situations in which this will not do.  Unless of course, there was a way to have the authentication done via PHP.

Share this post


Link to post
Share on other sites
I have seen a post on this a long time ago.....

The only thing I can think of is to store images in your database - that way they can olny be called from a script and you can control which script may call them....

But there is surely an easier way.

Share this post


Link to post
Share on other sites
put the
protection directives from the above FAQ inside of a FilesMatch
container like so:

<FilesMatch "secret.html$">
  AuthType Basic
  AuthName "Some Description"
  AuthUserFile /full/path/to/passwdfile
  Require valid-user 
</FilesMatch>

The match pattern is a regular expression, so it can be used to match
more than 1 file: <FilesMatch "(private|secret).html$">. That would
protect private.html and secret.html an no other files.

Share this post


Link to post
Share on other sites
Yes, I can password protect the directory, but I want to be able to authenticate users via PHP.  I don't want to have to go to my hosting utilities and add information for each username/password. 

I want to use a single username/password and have PHP do the authentication for users that have already been authenticated via PHP?MySQL.  Put another way, once users have logged into my site, I don't want them to again have to enter a username and password for the folder password protection.

Share this post


Link to post
Share on other sites
I dont understand what are you aking for.
Create a register/login etc' pages, then on each page (that is allowed only for users) check if the session var containing the username is set. If he has it (means- he's logged in)- continue. Else- redirect to login page and ask him to log in.

Orio.

Share this post


Link to post
Share on other sites
two ways of doing this.  first of all, any directory above your root is protected and inaccessible to web users.  they will show up as images because the server has access to the directory, but regular web users cannot directly hard-link to the images (how do you link to www.site.com/../image.jpg ?)  putting your images above the web root is therefore one way of protecting them from name-guessing.

second, you can use a PHP file as the source.  it may be a little slower, i've done no performance checks.  simply write a PHP file that takes the image source as a URL parameter (ie. $_GET['image'] or something similar), opens the image, grabs its content, and spits it out.  if used in an image tag as the source like so:

[code]<img src="grabImage.php?image=stuff.jpg" />[/code]

the output will be the image.  however, accessing grabImage.php?image=stuff.jpg directly simply outputs the image's JPEG data onto the screen rather than its visual translation.

for reference, getImage.php would look something like this:

[code]<?php

$source = 'images/'.$_GET['image'];

$handle = fopen($source, "r");
$output = fread($handle, filesize($source));
fclose($handle);

echo $output;

?>[/code]

despite the source giving away the name of the image itself, there are a few ways of stopping this from giving it all away; you can place them into a directory and manually prepend that to the filename (as i've done here), or you can use some sort of array=>filename and send the index rather than the filename like so:

[code]<?php
$files = array
(
  'top' => 'header.jpg'
);

$source = $files["{$_GET['image']}"];
?>

<img src="getImage.php?image=top" />[/code]

the first method is easiest and less tedious, as the second method requires that you explicitly make an array item for every image you want to protect this way.

Share this post


Link to post
Share on other sites
thank you!

putting the images above the root directory seems the best approach.  I'll try it out.

But another related question.

If I have a file or folder password protected on the server, i.e. via my web hosting utility, is there any way that I can authorize a user via PHP rather than have the username/password box popup?

Share this post


Link to post
Share on other sites
if you manually add the PHP protection and remove the basic HTTP authentication, then yes.  otherwise, no - basic HTTP authentication operates on the webserver level and is always used with the username/password box as far as i know.

Share this post


Link to post
Share on other sites
I think what you sould do (and what I do) is have an htaccess file in your images directory that doesn't show any files at all...so it doesn't really matter if people can see the directory or not.

As for your images...Make them random file names so when you upload house1.jpg it turns into cabd83r3d9.jpg (or whatever) then it will be pretty much impossible for people to guess what your file names are.

Hope this helps,
-Chris

Share this post


Link to post
Share on other sites
what about the $_SERVER variables PHP_AUTH_USR, etc.?  Are these not used for server authentication?

Share this post


Link to post
Share on other sites
Well, I password protected a directory through cpanel and I can access the files through my script , but if I were to try to directly access the files it will prompt for the password. Works out good.

Share this post


Link to post
Share on other sites
thanks everyone for your help, but, unfortunately, it isn't working for images.

if I put php files above the root directory or in a password protected folder, they can be executed from another directory using include() without being prompted for user/pass, just as hostfreak said and akitchin suggested.  But this approach does not work for images, whose source is defined within the HTML.

Share this post


Link to post
Share on other sites
http://www.clockwatchers.com/htaccess_images.html should do the trick... The only problem with
[code=php:0]
<?php

$source = 'images/'.$_GET['image'];

$handle = fopen($source, "r");
$output = fread($handle, filesize($source));
fclose($handle);

echo $output;

?>
[/code]
is that if someone knows its http://yoururl.com/image.php?image=Smith_Street1 they can just link to that... You could always just add some script to that so that it will only display it from yourdomain, but in my opinion htaccess is an easier approach...

Share this post


Link to post
Share on other sites
thanks very much for that link.  I did not know anything about .htaccess files.  Quite useful.

Share this post


Link to post
Share on other sites
Hehe grabbed that off google, took all of 2 seconds...

Anyways I was interested in the php aspect of it because I might use this for my self in the future... So i came up with
[code=php:0]
<?php
$url = $_SERVER['PHP_SELF'];
$url = explode("/", $url);
$count = count($url);

$slashcount = $count - 1;

$i = 0;
while($i < $slashcount) {
$slash .= "../";
$i++;
}

$str = $_SERVER['HTTP_REFERER'];
if(eregi('yourdomain.com', $str)){
$source = $slash . "directory_your_image_are_in/" . $_GET['image'];

$handle = fopen($source, "r");
$output = fread($handle, filesize($source));
fclose($handle);

echo $output;
}

?>
[/code]

It should work from /folder1/folder2/folder3/image.php or /image.php as long as its called to in an <img> tag... It checks the referrer to make sure its your site then if it is displays the picture...

Share this post


Link to post
Share on other sites
thank you.  Are you sure echo $output will actually produce an image onscreen?  I believe in a previous post someone said that it wouldn't, that the data read from the file must somehow be processed into an image. 

Also, do you think this method offers any advantages over the .htaccess approach?

Share this post


Link to post
Share on other sites
the output echoing will show an image if the PHP file is used as the source in an <img> tag, but will NOT produce an image if included or accessed directly.

Share this post


Link to post
Share on other sites
"as long as its called to in an <img> tag... It checks the referrer to make sure its your site then if it is displays the picture..."

Thats what i meant i just didnt feel like explaining it at 4 in the morning :D.. you could also use if($referrer == "") along with the one for a domain... People could go straight to the file... But they couldnt hot link to it... Which is what i assume youre tryin to prevent..

Share this post


Link to post
Share on other sites

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.