How to protect photos on the website?
Hi All,
I am developing a photo website. I am using Apache 2 HTTP Server with a Tomcat 5.5.9 container. I use the Jakarta commons Fileupload package to upload photos to the website.
I am storing all the usernames and the MD5 passwords in a progress database. Once the user is authenticated (i.e. after logging in), I put the LoginBean in the session, which will help the webserver identify the user for the subsequent visits.
The tomcat directory structure is as follows...
c:\Tomcat\webapps\photoapp\
c:\Tomcat\webapps\photoapp\images
c:\Tomcat\webapps\photoapp\images\user1\1.jpg
c:\Tomcat\webapps\photoapp\images\user2\1.jpg
When a user chooses to upload a photo, I upload it the user's directory.
How do I prevent user1 from seeing user2's photos?
Lets say user1 types http://photo.com/photoapp/images/user2/1.jpg, he/she shouldn't be able to see this photo.
Please advise. :)
Thank you!
Joe.
[985 byte] By [
Joe12a] at [2007-10-2 6:37:42]

Don't store the images in a publically accessible place like webapps\photoapp\images...
Put them in webapps\photoapp\WEB-INF\images...
Then make them accessed only thru a servlet which actually returns the image file data. In that way, you can make sure that the servlet only serves images from the user's direcory,
A couple of ways to do it.
1 - put a servlet filter on the /images/user* directory. That will intercept all requests to these directories, and you can handle the request there.
2 - put the photos under the WEB-INF directory, and only allow access to them through a servlet
ie <img src="imageServlet?image=245"/>
The ImageServlet would ensure that it only displays images belonging to the correct user.
It is also possible to put the images into the database in Blob fields, these could only be accessed via a jsp that streamed the images back out again.
Doing this also may make images easier to manage, I do not know how much of an overhead there would be in terms of system resources to do this on a high traffic site though.
Have you been able to find a solution yet? I'm looking for the EXACT same capability.
I figured a filter of some sort would be necessary but my biggest problem or question is how to tie in my own login security with that of Tomcat. Please correct me if I'm wrong, but a filter is a Tomcat entity, meaning that security is handled by tomcat via and of the CONFIDENTIAL, etc settings where a user has to specify the user/password pairs in some XML file. BUT in both of our cases, we store the user/password pairs in a database and hence do not rely on the Tomcat security (or for that matter Apache .htaccess like security), so HOW do you add a filter that relies on our own security?
Does that make sense? Probably not...it has me confused a bit and hence it is hard for me to describe it. This may help...I DO NOT want to have user/password pairs in some WEB.XML or context.xml file that have to be configured at the Server level and instead I want access tied to my own user/password validation system based on what I store in a database.
ughhh...please, please give me any suggestions or help that your have found. If not through this post, then please email me via
zaczekmariusz AT yahoo DOT com
Thanks.
>but a filter is a Tomcat entity, meaning that security is handled by tomcat
>via and of the CONFIDENTIAL, etc settings where a user has to specify
>the user/password pairs in some XML file.
No, a filter is not Tomcat specific. You CAN use Tomcats security if you so wish, but you don't have to.
A filter is just a "hook" for you to intercept requests and run some java code if you so wish.
Probably the simplest approach is to use the "ImageServlet" idea.
If you only provide access to the images via the "ImageServlet", then you have complete control over the request.
There's actually several methods.
One, as mentioned, is the servlet method where it's up to your servlet to do everything. Of course, by "everything", we do mean "everything".
Next, is the Filter method. This is nice because you can check authentication using the filter, and then simply chain the request with doFilter. What's handy here is then Tomcat serves up the actual file, rather than your servlet. Boiler plate code you you don't have to write, mime types you don't have to look up, etc.
Both the Servlet and Filter methods require you to implement your own authentication scheme. The granularity you're after pretty much mandates this anyway.
I prefer the Filter method, as it lets the container do what it does best -- serve up data. It's also pretty simple to do.
What I meant about the Filter being a server thing is that for using a Filter don't you specify the users and their passwords in the web.xml file for the users that can access the folder (or the filter)? So, if I have user/password pairs in a database then I can't change the web.xml file that easily...especially if I write a site that accepts new users and adds them to the database. In this case I would have to have a way to update the web.xml file with the new users and put their clear text passwords in there as well....but I have a encrypted/encoded password. I could be wrong on my assumption of what a Filter does because I need to read up on it again.
The answer that someone posted about using an Image Servlet is fine if all I'm serving is images....but imagine if I have a site where I want to sell some Program (say ZoneAlarm, or Windows, etc) and I want someone to be able to download it once they pay and setup an account...or maybe a site where I give someone a bit of harddrive space where they can store their own files and they don't want anyone else to view those files (docs, text, images, pdfs, etc). But I want them to be able to get a direct link to the file instead of going through a servlet...I want them to be able to type:
http://mysite/companyAprivatefolder/secret.pdf
and say company B comes along and types the same thing it, I don't want them to be able to get access to this...of course if I put a filter on this directory to force it to go through a servlet then I could manage who gets the files. That is true, but say I don't want to do a filter...and grant you that may be a stupid way to go but it seems more logical and easy to me.
In my searching, I found what I believe may be the answer and maybe any of you can comment....I found that REALMS are what I should use. REALMS are set in the server.xml file and can be based on a Database user/password pair and user role tables...I have to read about this more but I think this is what I might be able to use. I'm just worried that I may not be able to have encrypted/encoded passwords stored in my database in order to use it with a REALM but I'll see.
So, if any of you can comment on what I wrote I'd greatly appreciate it...you've been very informative thus far. Thank you.
Mario
You can create temp links that will be valid during the restricted time.See this component in JSOS for example: http://www.servletsuite.com/servlets/securelinkflt.htm
> In my searching, I found what I believe may be the
> answer and maybe any of you can comment....I found
> that REALMS are what I should use. REALMS are set in
> the server.xml file and can be based on a Database
> user/password pair and user role tables...I have to
> read about this more but I think this is what I might
> be able to use. I'm just worried that I may not be
> able to have encrypted/encoded passwords stored in my
> database in order to use it with a REALM but I'll
> see.
The problem with REALMS are two fold. One, they're Tomcat specific and not portable to another container. And, two, Tomcat Realms are only used to specify the user credentials, but the actual mapping is still done within the web.xml file, which is something you do not want.
The Filter is your best mechanism. You can create an all encompassing filter that intercepts all traffic in to the container, and from there you can redirect traffic however you wish. Typically this is done by placing tokens in the session with the user credential. If you can't find the credential in the session, then redirect them to a login/register page.
By putting this in a filter, it will work with any resource served by the container -- servlets, jsps, images, pdfs, etc.
Using URL mapping in web.xml, you can include or exclude any resource you like, or you can simply do all of the mapping within your filter and punt on web.xml completely.
>What I meant about the Filter being a server thing is that for using a
>Filter don't you specify the users and their passwords in the web.xml
>file for the users that can access the folder (or the filter)?
No. A filter has absolutely nothing to do with usernames/passwords.
http://java.sun.com/products/servlet/Filters.html
You set it up in web.xml like this:
<filter>
<filter-name>PrivateAreaFilter</filter-name>
<filter-class>com.PrivateAreaFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PrivateAreaFilter</filter-name>
<url-pattern>/privatefolder/*<url-pattern>
</filter-mapping>
any time anyone tries to access anything under the url /privatefolder/ it will invoke your filters "doFilter()" method.
In that method you can check their credentials, and either allow it to go on, or veto the whole transaction.
The whole thing about Realms is just where you look up usernames/passwords. You still need to exercise control over what is revealed.
Maybe this link will help? I can't say I've done this before, but it looks relevant.
http://tomcat.apache.org/tomcat-5.5-doc/config/host.html#User%20Web%20Applications
One method that works very well is stamping the images with user's name. This approach allows you to know who stole your image if you find a copy floating on the internet or a Peer-to-Peer network.
So what's so great about knowing WHO STOLE your image? If you collected their CREDIT CARD numbers, you can charge them!!! In practice, it's a strong enough deterrent that people don't steal images.
Newer generation software can embed the user's name into the image. This stamp persists even after screen-capturing, cropping, etc.
A company that does this as a subscription service is:
http://www.catchlock.com/
I have a small problem with doing the filter method...I understand you can use the filter method to lock a particular directory and force anyone accessing it to go through the doFilter() function that is designated...that's all fine but what if I have this situation:
I not only store a program or file for download but I also store the logo image for the company or some image that I want displayed on the download page...how do I serve that? I do I still have the image display in the window for a particular user but not be able to be accessed directly?
So I have this:
directory_company1/
download_file_1.exe
logo_image_1.jpg
index.html
directory_company2/
download_file_2.exe
logo_image_2.jpg
index.html
When a user from Company 1 logs in, he access the index.html file in that companies directory (or even the image)....but with this filter in place won't the code force me to go to a doFilter() function and not display the index.html file? How would I tell the doFilter() function to show the index.html or for that matter, what if doFilter() shows a display for the particular company user that is logged in, how does it display the image file from the directory? I mean, can I just have an output line that directly links to the image?
out.println("<img src=http://mysite/directory_company1/log_image_1.jpg>");
Will that work, or will the filter interfere with this in some way?
gosh I hopes all of that made some sense...
If you want to protect the images stored on the server and in cache, consider using encrypted images that are displayed in a security applet. I'm surprised the option is not mentioned here because its been available since 1998.
If you want to further protect images from screen capture and printscreen, that solution is also available.
Of course there are workarounds to these solutions, but they have been the most secure solutions available since 1998 and it doesn't get better... no-one has comparable solutions despite their claims to the contrary.
Banks and online surveys use these solutions and they are the best available!
Want to know more?
See their demo site at www.artistscope.com
I don't want to protect the images from screencapture, etc....I could care less if they steal it or not.
What I'm trying to protect is a user from one company having direct access to another company's image...whatever the image may (or some other file).
Even if the user is of the same company they should not be able to see the picture (file,etc) unless they log in....if I don't store the data in a database and instead store it in a folder on the server what prevents someone from accessing this folder. Some mention that you can impose a filter but then to access the file you have to provide a filter method to do so...but I want to be able to return a JSP or HTML page that has the image displayed and I don't want to have to go through some filter method to do so.
I figure there should be a simple way like you have with .htaccess where unless you are logged in then you cannot view the file...but if you are logged in then you can use the file in any way you want, you can imbed it in html pages or you can link directly to it.With .htaccess I can setup multiple directories and limit who has access to which directory...sort of like I'd like to do with Java.
