Saving sensitive images in database or in web-directory? - php

I'm developing an online photo proof system for clients where the client is given a password and has to log in to see their albums. Some of the images may be sensitive/naked photos, which should not be available to other people.
But if a hacker was very clever he/she could just type in the URL. But then again he would have to know every name of the images and the exact folder-structure... The server is set up so that you have to know the exact url. You don't have permission to see folder-structure /file-trees. I can't override the .htaccess file.
Is this a security risk that should make me store images in a mySQL database instead of saving the files to a directory?
Thanks in advance.

Create a long random string and save it corresponding to user.Then it will be hard to brute force and limit frontend access limited to user by checking the credentials

Put flags in the db for ever img id, i.e. 1 for public 2 for adult, so if the user, when uploads, checks it's adult content, you insert a flag "2" in the DB. So, afterwards, make a check if the requested image has flag 1, and if false, then go to check if the $_SESSION is populated with the user owner's one, if it's foreigners sessions - don't show the content.

Related

How to let users upload a file to my server allowing them to re-download that file with an appended string

I am building a very basic site for an online MMO PC Game (Note: Game has a built in API). I need the ability to allow users to upload a "character settings" file from their game settings directory on their PC to my web server. Once the file is uploaded they need to be able to modify the file name, to apply them to another character on the server, and to re-download the files.
Example: I have a character named Tom. Each character has two settings files associated with it:
core_user_1234567.dat
core_char_12345678.dat files
I have another character named Jerry. I want to set him up with the same exact settings as Tom. To do this I want to upload Tom's settings files to the web server, input Jerry's userID and characterID values into a form, and re-download the files with those values appended while removing the old values from the uploaded file names. This essentially replaces the core_user_"this".dat to core_user_"that".dat.
The steps I need to complete in order to get the functionality I require for the app to work.
Step 1.) The user obtains the UserID and CharacterID for Tom from the games server by calling the games API for that character. (User enters his API key into a form and submits. This will return the two values to be displayed in the browser. This is simply a reference call so i can display the values to the user in the browser so that the user knows which two settings files correspond to the character he is trying to clone (in this case Tom). There may be many sets of settings files already in the folder. (This step I can achieve already).
Step 2.) Once the user knows which two settings files belong to Tom the user then locates and uploads Toms settings files to the webserver.
Step 3.) Now, once the files are on the server the user needs to obtain the userID and characterID for Jerry. I do the same thing as in Step 1. Make an API call and display the returned value to the browser so the user knows the values.
Step 4.) The user can then insert the values into a form and submit it. Once submitted the values are appended onto the settings files that are temporarily being stored on the server and a download link is generated.
Step 5.) User downloads the new settings files to the settings directory and it's done. Jerry now has the same settings files as Tom.
EDIT: My inquiry is regarding step 2 and step 5. The PHP side of things. How does one write this simple upload script. Upload the file, pass in a string to the file name replacing everything after the second _ and before the .dat, then generate the download link? core_user_"replacethisstring".dat
Your question is still rather broad, but I'll happily offer some pointers. It seems the bit you need some help with is the PHP code. Here are the broad steps I think you need:
A login/logout system to identify individual users
A profile page for users to specify their user and character IDs
A file upload form (e.g. for Tom)
A download form (e.g. for Jerry), in which Jerry's userID and characterID are specified
A system to modify uploaded files
So, Tom logs in, and uploads his two files using the upload form. They are stored in a folder named after his user ID, so they don't get mixed up with anyone else's files. One is called "core_user" and the other is called "core_char" (since longer suffixes are redundant here).
Jerry now logs in. He inputs his own "userID" and "characterID" into the download form. Does he also need to specify that he wishes to clone Tom's files, and not Road Runner's? If so, he does that at this stage. The page then shows him two download links, one for each file.
When he clicks on each, they are dynamically generated from the target user, with the modifications based on the downloader's own details. This could additionally be stored as a file for this user, but it is not necessary at this stage. To do this step, read the file using file_get_contents, modify it using string manipulation functions, and then echo it to the browser. If you use the appropriate headers, it will appear as a downloadable file, rather than a text document.
It is arguable that Jerry does not need to specify his userID and characterID in the download form, since if he has logged in, these can be obtained from his profile.
You'll notice that I've not mentioned an API here - I'm not entirely sure what that is in your context, but it may be a distraction in the first cut. Get the simplest possible version working first.
So, here the problem is broken down a great deal more. If you find a sub-problem insurmountable, then it is possible it needs to be broken down again, until each thing is a PHP call or an HTML form.

PHP create folder, upload file and allow delete file best security measure

I am developing an application that allows users to upload images. The script creates multiple sizes of the image and stores them in folders with a session ID e.g. /uploads/skj28cnkjck783wo/thumbnails before renaming the folder to a unique name once the user hits submit/next/go.
I need to allow users to have the ability to remove individual files but wondering what the best secure way of doing this would be. If I base the delete off the session ID surely users would be able to change this and remove files that don't belong to them.
I was thinking I could store user information and the object reference in a table and do a lookup to ensure that user has access to remove that file or store the files in a folder with the user ID which is unique based on DB entry but wondering what the experts think. I have done some Google searching but all have flaws.
I am running IIS7 as the web server.
Thanks
Try to store relations "userName(or userID)"->"UserFile" in separate table. This is the best secure way, bacause OS (Windows in your case) can detect only one user - owner of web service (IIS or Apache, etc.)
It is you who manipulates the files, not the user himself.
The user gives the file name (or perhaps some file id) in his GET or POST request.
Disallow relative paths by rejecting all inputs that contain slashes. It's easy if you don't allow subfolders.
If you allow subfolders, reject all that have ../ etc.
You can keep files by changing their names (like flickr does), and keeping data of the filename (to show to the user) and the owner. If owner and user do not match, reject.

Alternate way to upload files in folders

Actually this is about a cloud storage web app
A web app where user have their own private folder and i want they should have their own folders too .What could be the best way, to tell uploader that the file being uploaded has to be in specific folder in which user is in.
So what i thought is whenever a folder is created and opened a session which stores folder name is started and sent to uploader where Uploader that way uploads.
For eg $_SESSION['folder-name']='x'
$upload_dir= "/$_SESSION['username']/$_SESSION['folder-name']/"
Every user has specific private directory where they can upload files. So there is no chance that session can be manipulated to upload in wrong user directory.
Since now i see this way as the best way, is there any alternative i can get from stackoverflow community on this . if yes, please describe
Since your username is unique I suppose then I seems legit.
But lets see this scenario:
A user get's deleted and another one registers with the same username...
EDIT
It depends on the fs and many other factors. Eg is this going to be url accessible ?
An legit alternative could be:
Since the username as you set it seems to be unique then you could first md5 it (is quick) and then digest to hex if you want it shorter and url accessible. That will give you a good number of usernames that can be converted to folders.
Bad thing about this is that you can't find the user by the folder name. If you had that in mind
That's it.

Integrating Facebook login with own user database

Maybe a 1000 times asked question but I could not find and sophisticated answer.
I have a PHP/MySQL user login system (session based) with a own users database. The structure features some user data like age, about me etc.
I can do this all in the means of programming, no problem, however - I have some "concept" issues that I hoped someone could advise me at:
Let's say that my user database features some field that FB does not cover. Should I ask for them let's say when the user first logs in with FB?
Better to take the profile PIC and save it locally or read it from remote server?
Better to save the FB data (like name, about me etc.) locally or read it from remote server all the time?
Let's say that my user database features some field that FB does not cover. Should I ask for them let's say when the user first logs in with FB?
It would be rather nice to allow user to add them later or prompt them that their few information can be updated
Better to take the profile PIC and save it locally or read it from remote server?
Depends, if you want to display the profile pic of the user to reflect his present state then use the profile image link and if you have the space to store all the image of the users then it is better to go with the local storage, although it might not be updated, but you can add selection option to upload new.
Better to save the FB data (like name, about me etc.) locally or read it from remote server all the time?
Now for this I would suggest that you make the copy of the information you have retrieved locally, for the purpose of speed, cause getting the values back again and again takes toll on the page speed and hence the user experience.
1) I would stick with some defaults and avoid requiring much of a user who may just want to browse around at first and let them fill in later when they get more involved and want to share.
2) I thought the facebook profile pic was a url dependent on user id. just attach the user id into an image link.
3) I think there are some rules about the data you can save and the data you cannot; a bit faster to serve it up if you already have it, but it can grow stale. So probably fetch it again after 24 hours or some other reasonable time frame. i.e. keep it in a cache, and fetch again if stale, clear your cache if stale to make room for more recent queries.

Secure way to store files in web server?

I want my files to be secure in my web server. Only authenticated users to access those files should be able to access those files. I thought of storing files in database as "Long BLOB" but it supports only upto 2MB of data. The file size may exceed beyond 50MB. is there any other better way to secure the files? please help me.thanks in advance.
Don't store them in a database. Put them in your web directory and secure them using .htaccess.
If you want to authenticate via other means, then store the files in a directory that isn't web-accessible but is readable by the user php runs as.
Discussion
If you opt to keep high value downloadable content files directly on the filesystem, the best thing to do is to keep them outside of the webroot.
Then, your application will have to solve the problem of creating URLs (url encoding when necessary) for content (PDF's, Word Docs, Songs, etc..).
Generally, this can be achieved by using a query to retrieve the file path, then using the file path to send content to the user (with header() etc ..) when he or she clicks on an anchor (all of this without the user ever seeing the true, server side file path).
If you do not want user A sharing URLs for high value downloadable content to user B, then your application must somehow make the links exclusively tied to user A. What can be done? Where should I start?
Obviously, you want to make sure user A is logged in during a session before he or she can download a file. What is not so obvious is how to prevent a logged in user B from using a URL sent from user A (to user B) to download A's digital content.
Using $_SESSION to store the logged in user's ID (numerical, or string) and making that part of the eventual query (assuming content is tied to user purchases or something) will prevent a logged in user B from downloading things they have not purchased, but you will still incur the resource hit for processing the SQL empty set for items they have not purchased. This sounds like a good step two.
What about step one? Is there something that can prevent the need to do a query to begin with?
Well, let us see. In HTML forms, one might use a XSRF token in a hidden field to verify that a submitted form actually originated from the web server that receives the POST/GET request. One token is used for the entire form.
Given a page of user specific things to download (anchors), one could embed a single token (the same token, but different per page request) into each anchor's href attribute in the form of a query string parameter and store a copy of this token in $_SESSION.
Now, when a logged in user B attempts to use a logged in user A's shared URL, the whole thing fails because user A and user B have different sessions (or, no session at all), and thus different tokens. In other words, "My link is the same as yours, but different." Anchors would be tied to the session, not just to the page, user, or content.
With that system in place, PHP can determine if a request for content is valid without getting the database involved (by comparing the submitted token to the one in $_SESSION). What is more, a time limit can be established in $_SESSION to limit the duration/lifetime of a valid XSRF token. Just use the time() function and basic math. Sixty minutes might be an ideal token lifetime for an anchor in this situation. Have the user login again if the token for a clicked anchor has expired.
Summary
If you use files on a filesystem and store the paths in the database, make sure you do the following (at minimum), too.
Apply proper file permissions to your content directory (outside of webroot).
Use random names for uploaded files.
Check for duplicate file names before saving a file from an upload.
Only logged in users should be able to download high value content.
Have an effective $_SESSION system that deters session fixation.
Make URLs for high value downloadable content unique per page by using hashed XSRF tokens.
XSRF tokens cover more scenarios when they have a terminal life time.
Make SQL queries for user content based on the logged in user's ID, not the product exclusively.
Filter and validate all user input.
Use prepared statements with SQL queries.
A few options come to mind.
If you are using Apache you can use htaccess to password protect directories. (first googled link : http://www.javascriptkit.com/howto/htaccess3.shtml)
or
Store the files above the web server.
Create a script in php that will allow authorised users to access them.
If you want to do it Via FTP, and you are running cpanel you may be able to create new ftp accounts. check yourdomain.com/cpanel to determine if you have it installed.
Storing files in DB is very bad practice. Very good practice to store only information about file. Name, extension. Files save on server like $id.$ext. It will be a good architecture. And when user download file, he take file with name in DB.Sorry for my english.
The best way is to store the file reference in Database. The file itself will be stored in the server filesystem. The complexity of this is making sure there is reference integrity between the database file reference and the existing file in the server filesystem. Some database such as sql server 2008 have feature that maintain the integrity of the file references to the actual file itself.
Other than that securing the file itself in the server depends on the OS where permissions can be configured to the specific folder where the file reside.
If the files are purely static you could use read-only or WORM media to store the data files or indeed run the complete web server from a "LiveCD". It's certainly not suited to everyone's needs but for limited cases where the integrity of the data is paramount it works.
Downloadable files can be stored in htaccess protected folder/s. A script like the one below can be used to generate dynamic links for downloadable files.
for ex. Secure download links. http://codecanyon.net/item/secure-download-links/309295

Categories