How to make upload folder private

How do I make user-uploaded files private if I don't have a private folder? I use a shared remote linux host.
Torquil BeavisBusinessAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Please explain what you mean/need.  An upload folder usually only has write access no read access.

Under what share is it? How is it accessed?
Torquil BeavisBusinessAuthor Commented:
I need to have a secure folder for my users to upload images to. My understanding so far is that I need a private folder outside my root in order to secure the files (among other safeguards), otherwise anything could be uploaded inside the root's folders.

I use a web host that has a shared host server running apache, remote from me. I have no access to the host except through ftp and ssh.

Here is the folder structure where [sc] = shortcut symbol:
/[sc]public_html (points to /web)
/[sc]my web site name without the .com (points to root)
/web/my web site folders

Open in new window

Apparently, most hosts allow access outside the root for private folders, this being more secure than inside the root.
Incidentally, my web app is in PHP/MySql, and images that I intend to have users provide will be .jpg, .png, and .gif. These images would be stored in the private folder and pointed to by db entries, since storing the images would use too much db space.
The issue is that permissions on folders are controlled, often it is suggested/recommended to have a private folder outside the path deals with avoiding mistakes, I.e. Person A places a file in the HTML folder. On access attempt, the person gets an access denied error.  Since this was a common occupancy when initial setup, the firm/admins created a script/command set to run to correct the issue on the entire HTML directory allowing read access ...
The impact if the private folder is in the oath, the write permissions will be removed while read permissions will be added.

The DB can point to ip the uploaded images, but unless a process exists that relocates the images from the private upload folder into a public/readable folder, the images would only be viewable on a page if there is a server based process that will stream the data.  A link referencing the image in the private folder will get an error, access denied.
Discover the Answer to Productive IT

Discover app within WatchGuard's Wi-Fi Cloud helps you optimize W-Fi user experience with the most complete set of visibility, troubleshooting, and network health features. Quickly pinpointing network problems will lead to more happy users and most importantly, productive IT.

Torquil BeavisBusinessAuthor Commented:
So, does this mean I do not have access to a private folder?
And what server-based process would be needed to stream the image?

So if I had a private folder where uploads landed, then I could test the uploaded file, and if it passed, then have PHP read the file and write it to one of my web folders?
When the folder is private, it usually means that the person uploading into it can not see the contents of the folder.

The process I am talking about deals with moving the files from the private folder to a readable folder.  This serves multiple purposes including approval process to make sure the image uploaded conforms to your standards.
The image is not a trojan horse with a virus payload.

A streaming mechanism means that you have a image.php?imageid=123
the image.php locates the imageid reference in the database, then accesses the location of the image and then responds with the
there are different tools within php to handle the stream.  I.e. open the image
and then send the contents to the browser with correct type There are built-in function that will auto-detect and send the correct type.
Content-type: image/jpeg

and the image source/data.

Deals with limiting/controlling access to the image without having to recode. i.e. the images uploaded is the user's picture/icon. When they change the image, the update in the DB for user picture/icon is updated with the new image, and .........
Torquil BeavisBusinessAuthor Commented:
Let's see if I understand this correctly.
If I had a private folder where uploads landed, then I could test the uploaded file, and if it passed according to my standards,  my PHP script could read the file and write it to one of my web folders, then insert the address and filename into the db? LIkewise, if the user wanted to update the image, except it would be a db update.
Yes that is one option.  Privacy will be enforced by your PHP web application and the web server.
since the web server runs as effectively (nobody, apache meaning the user has the most limited/restricted rights) such that you would need to grant the user apache/nobody rights to write into the folder your PHP script will use as the destination of the file/s being uploaded.,
Often this folder is placed just one level outside the RootDirectory of the web site. i.e. if your web accessible path is /var/www/html the private folder would be in /var/www/domain_private_folder. I do not believe your PHP web interface would be able to relocate the files from the private_folder to a readable folder because of the restrictions mentioned previously that /var/www/html is usually restricted to read only by apache/nobody.

To achive the relocation of a file from the private folder to lets say the images folder which are in /var/www/html/images will involve a process (possibly running through cron) which looks at your mysql images table, for a particular indicator such as a column says approved. at which point this process will copy/move the image from the referenced current location private/image1.jpg to images/image1.jpg while at the same time updating the database reference and "publishing" the image within the DB structure you have.
Torquil BeavisBusinessAuthor Commented:
1. So, I take it that from the folder structure above, that I do not have a private folder (even though it shows 'public_html')?

2. If 1. is true, then the issue is, firstly, whether I can get a private folder, and secondly, what process I can discover that will allow a move from that private folder to the public folder. Right?

... Hold it: I just read this: "The public_html folder is the web root for your primary domain name. This means that public_html is the folder where you put all website files which you want to appear when someone types your main domain (the one you provided when you signed up for hosting)."  When you talk about 'root', are you talking 'web root' or the one that has the web root as one of it's folders? And if the root we are discussing is web root, then surely I can create a private folder above 'web'?
What is your server/setup like?  Do you manage access or someone else has to be asked to create/assign rights to a folder?
public_html is often only used for user based configuration in apache i.e. will translate to the username's home dir/public_html.
These types of sites are highly restrictive/restricted to avoid users creating pages/functions that could expose the system or ......... worse.
Torquil BeavisBusinessAuthor Commented:
I can create/assign chmod via ftp or ssh.
Torquil BeavisBusinessAuthor Commented:
Solution ..

Here is my directory structure:
root (.com root on my shared remote apache web host)
/[sc]public_html (points to /web)
/[sc]my web site name without the .com (points to  .com root)
/web [Note: This is the WEB root folder]
/web/my web site folders

Open in new window

I created private folders like this:

Open in new window

I created include files in /private where they cannot be read by the browser but I can include them with:

Open in new window

The data goes in /data which needs world rw access and can be opened like this (example from w3schools):
$myfile = fopen("../data/webdictionary.txt", "r") or die("Unable to open file!");
echo fread($myfile,filesize("../data/webdictionary.txt"));

Open in new window

So the calling file within /web calls the include file in /private which reads the text file in /data.

I tried getting the include file to run directly from the browser (not through the /web calling script) and it could not find the file. Also, I tried getting the text file from the /data text file directly from the browser and it couldn't find the file.
This is what I expected to happen because only public files under the /web folder are accessible via a url.

This means the folder structure makes the /web folder files safe against users who might try to gain access to /web files using uploads to /data files - hackers aside.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Torquil BeavisBusinessAuthor Commented:
I selected my own comment as the solution since the expert advice needed me to do more work in determining that a private folder could be created outside the /web folder which turned out to be the web root. Consequently, the solution was to handle upload data and files through a script in the web folder which has access to the private folders while users may not.

Thanks arnold. Your help is much appreciated.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Linux Security

From novice to tech pro — start learning today.