I have a quick question if anyone could help. I am building a CMS for a client where they can log in, and change content (including pictures via upload file form) that are all stored in a database.
My question.. I have been researching, and everywhere says I need to store the image files outside the root folder. Is this necessary in my case if only a few people will be uploading files, inside an admin panel, where they must first log in to the site? I will have already taken steps client side by making sure of file type, size, extension etc... then changing the name of the file before adding it to my DB... Is this secure enough, or am I asking for trouble down the road?
Thanks
Its generally a good idea to store uploaded content someplace where it cant directly be addressed by a browser. You dont want someone uploading a .php file (or some other format you forgot to check for) and then being able execute it by pulling up the direct url. Rather, you'd have a wrapper script that delivered the file.
So yes, its a good idea, but not 'necessary' (by the dictionary definition of the word). You can certainly choose not to do so if in your judgement the admin area is otherwise secure.
That said, in the scenario you describe, as long as its only admin users who can upload images, I dont think its a huge deal either way.
btw, if you are not already, verify the images by their file headers or content, not file extension.
Related
I'm working on a portal that requires users to upload the images which wil be shown in a certain HTML pages. What should be the good practice here ?
Should I avoid uploading and ask users to give their own URL for the images ?
Ask users to upload image files.
Since we know, an image can be a deadly one if it contains code injection, but what about the remote ones, are they secure ?
Thanks
It depends on your website consistency. Uploading is much better than entering URL for example if the targeted audience is a professional clients they would prefer uploading as it would be difficult to explain to them what is a remote url and how to get it. But uploading is a more traditional way and feels more easy.
On the other hand if most of your targeted audience is internet users then there might be no need to give upload option. But as I said uploading feels much more natural and easy to users. It also depends on the type of images, if the images are the user's avatar then uploading would fit and if the users are adding images to your website to only share images they found from other websites then remote url would be more appropriate.
Both uploading and fetching remote ones to your server could be deadly, but if you use remote ones just to store the urls in your database then it will create no security problem.
So if you want upload feature or storing the remote images to your server you must do some certain steps to ensure the security of your server:
Verify the file extension and mime to be of valid image. (Don't rely only on this.)
Verify it's a valid image file (using php getimagesize)
Resize and copy the image into a new image object. And store that image into your server.
The folder where you are going to store must have all kinds of code executions disabled by using .htaccess (SetHandler default-handler)
Well, it depends on the nature of the project.
In fact any method could be fine, but you should validate and filter the user input.
There is a lot of options to validate a file if it is an image or not.
The getimagesize() function from php could be mentioned as an example, since every image file has to have a resolution and other relevant data.
There are other questions on SO here which answer yours too, you just need to take a look.
Validate image file php
In addition to Ghulam Ali's suggestions:
Make sure to sanitise the filenames. Best is to generate new filenames for user uploaded media.
Have the upload directory with only writable user permissions but that might lead to some complications.
Apart from tackling the security issues, you will also need to figure other important stuff such as orientation as media taken from a mobile device may have random orientations.
This is a best practice question regarding how to handle user uploads and distribute static content to a large number of concurrent users.
I have an upload form for images (png, jpg, gif) and other forms of multimedia (mp4, webm). The files are created, hashed, and stored in storage/app/attachments/ as their hash with no extension.
The request URL /file/md5/filename (such as /file/9d42b752ecd0e3b4542aeca21c7c50a9/dancing_cat.gif) will distribute the file with that name. The route is completely flexible, so replacing dancing_cat.gif with boring_cat_dancing_poorly.gif will still fetch the same file, but will distribute it with the new filename specified.
The point of this system is to stop duplicates from being uploaded while preserving the original name of the document that the uploader had. Other instances of the same file uploaded will also keep their name.
The code I have for this works, however, people raise issue with distributing static content through PHP. I am told that on my large, target platform, this system will work poorly and will immediately become a bottleneck. I am told I should use routes in Apache/nginx/Lighhttpd/whatever webserver to try and serve the static file directly by capturing the request URL before it hits PHP, but that may cause issues with mime types (i.e. an image won't render correctly).
My question is: What is the best practice for achieving what I am doing? How would a big website handle distributing static, user-uploaded content while avoiding a "PHP Bottleneck". I am early enough into my project to consider major rewrites, so please be as informative as possible.
I hope im clear whats the problem but, you may try to hash your current user name and file name plus file extension with sha1 or any shorter encoder wich generates a hash and its barely hard to generate same hash with theese combinations and add that generated hash to file name saved in ur dir. for example
/file/9d42b752ecd0e3b4542aeca21c7c50a9/gifhse3peo40ed-user_photo.jpg
You may then distribute hashes per user for example creating specific folder for specific user to save his uploads so when user reuploads any file the code will know where to save vice versa.
Hope it helps!
Since I am just experimenting on this, (only localhost) I may like to ask for some ideas(since nothing is really coming out of my mind) about letting a user, who is going to, for example, register to a mini-social-networking site, with a corresponding username/password, personal details, etc. I would upload the image, and save it to a folder(ON MY HARD DRIVE be it Drive C:\ or D:), for example '/images/username' and the full path of the folder would be the one inserted to a row named img_dir (of course it is a string, instead of putting it as a BLOB, so later i would just use img src="path"). I would not mind where it will be going to be saved. But since I am new to cakephp i haven't really grasped the idea of what I am going to do. I have no problems about registering/login sessions. This was easy in C# but I am too stupid for PHP maybe? :P
While this may not give you a direct solution in CakePHP, you had asked for some ideas.
I've outlines some pros and cons of storing a file on the filesystem (along with some other approaches) in this post.
Hope that helps...
I've written a complete plugin for that kind of task and it's more thought through then just the idea of saving the file path.
A file has some more meta data like it's size and mime type which is useful when the file is served. So an uploaded file should be handled as an entity of it's own. I personally think it is a bad idea to directly save the path to a file within the record it belongs to. What happens if you need two images later? Adding incrementing fields like path1, path2?
It is IMO better to have a separate table for files and associate records with these file records. Expressed in CakePHP associations: User hasOne Avatar or Gallery hasMany Image for example.
Also saving files in path like this uploads\username1\pic.jpg can result in slowing down the app because of file system performance issues if you get a lot directories and files within the same level of the file system.
However, check my plugins readme.md out, there is more about why it does things like it does to solve different kinds of issues you can run into.
In my application, I have a provision for users to upload files like doc, xls, zip, etc. I would like to know how to store these files on my website and have only restricted people access it. I may have a group of people and let only these group access those uploaded files. I know that some may try to just copy the link to the document or the file and pass it to another (non-permitted) user and they can download it. So how can I prevent it? How can I check if the request to download the file was made by a legitimate user who has access to the file? The usernames of the group members are stored in the database along with the document name and location in the database so they can access it. But how do I prevent non-permitted users from being able to access that confidential data in all ways?
With the above in mind, how do I store these documents? Do I store the documents in a blob column in the Database or just just let user upload to a folder and merely store the path to the file in the database? The security of the documents is of utmost importance. So any procedure that could facilitate this feature would definitely help. I am not into Object Oriented programming so if you have a simpler code that you would like to share with me, I would greatly appreciate it.
Also how do I archive documents that are old? Like say there are documents that are 1 year old and I want to conserve my website space by archiving them but still make them available to the user when they need it. How do I go about this?
Thank you.
Store them as a BLOB in the database. That way you can associate files to user groups and have security restrictions as you would normally do with users-related websites.
Decided to throw in an answer anyhow ;)
Here's a simple, but I think useful (haven't used it myself, just quickly found it for you) guide to uploading and downloading files to/from databases.
The uploading part of it looks good, but don't use the part of the download section that wants to echo links to the files - I don't think that's what you want. Echo the file contents immediately instead as the tutorial also describes, remembering to set the header.
I'm building a site were users can upload images and then "use" them. What I would like is some thoughts and ideas about how to manage temporary uploads.
For example, a user uploads an image but decides not to do anything with it and just leaves the site. I have then either uploaded the file to the server, or loaded it to the server memory, but how do I know when the image can be removed? First, I thought of just having a temporary upload folder which is emptied periodically, but it feels like there must be something better?
BTW I'm using cakePHP and MySQL. Although images are stored on the server, only the location is stored in the dbb.
Save the information about file to MySQL, and save the last time the image was viewed - can be done via some script that would be altered everytime the image is being used.. and check the database for images not used for 30 days, delete them..
You could try to define a "session" in some way and give the user some information about it. For example, in SO, there is a popup when you started an answer but try to leave the site (and your answer would be lost). You could do the same and delete the uploaded image if the user proceeds. Of course, you can still use a timeout or some other rules (maximum image folder size etc.).
I'm not sure what does "temporary upload" mean in your app. The file is either uploaded or not, and under the ownership of a user. If a user doesn't want to do anything at the moment, you have no other choice but to leave the file where it is.
What you can do is put a warning somewhere on your image management page about unused images, but removing them yourself seems like a bad practice (at least from the user perspective).
As a user,When I upload the image to a server(assuming I want to use it later) and leave the site, I don't expect it to be deleted if I am a registered user.
I would prefer it to be there in my acct until I come back.I would suggest thinking in those lines and implementing a solution to save the users' images if possible.
Check the last accessed/modified time of file to see it if has been used.