I am working for a paranoid client. The image uploader I've written must be able to 'survive' multiple penetration tests from some hired guys. Just for some background information: The images are for profile pictures only.
So, what I've got. I've got a HTML form to upload files, and the form can only be accessed by logged in users. The login system is safe, there's no worrying in that. Every user gets an unique user id, which is what I use to identify different users.
Whenever a file gets uploaded, I do the following checks on it:
The file must be larger than 128 bytes (stop ddossing)
The file must be smaller than 100 kb (the pictures will be displayed as 64x64 anyway)
Both of those checks are done with $_FILES["fileToUpload"]["size"]
The file's extension has to be '.png' (done with $imageFileType = pathinfo($target_file,PATHINFO_EXTENSION);)
The mime content must be "image/png" (done with mime_content_type($_FILES["fileToUpload"]["tmp_name"]))
The file will be renamed to $current_user->ID.".png"
All profile images are stored in /resources/img/profilepic/[userid].png
The file is moved with move_uploaded_file
Loading of the images is done within <img> tags. The code that gets the complete sentence (including the tags) is require'd in another .php file later.
So in short: The files are not named after the original but after [id].png. I haven't been able to find questions which address this too.
Is this bullet proof? Or is my current system just a nice challenge for someone willing to upload a web-shell? If there's a major vulnerability, how can I protect myself against it?
Related
So I've built a form that lets users to upload files (within an extensions whitelist) to random-named directories, under another directory in root. The random name, for tech reasons, for now it's written down in the html page, but visible in code only while the page exists. If the user refreshes the page, the name will change. Only the random dir name itself is visible, not the entire upload in itpath.
data-name="<?php echo uniqidReal(); ?>" // outputs like 'd91806dbde743568'
That name is then used by php to create the dir where the files will be saved, something like https://www.acme.com/mydir/d91806dbde743568/file.mp3. That entire url will be then send once to the receiver of the form.
The 'mydir' contents are under -Indexes, so no way for anyone to guess the name of the random named dirs in it.
Now my question: is that enough to avoid security issues? Could one, for example, upload a masked file that contains some malicious code that once uploaded can read the dirs and send them back informations or do something else?
Should I strengthen the security level in some other way?
This is not the best way, because the name of a folder can have characters like ../
It seems to me better to create a random folder on the server without receiving data from the user
My question is about HTML and PHP.
This is my setup right now:
A website where user have accounts
A FTP server with pictures (currently none)
Files are currently saved on the website in the "PICTURES" folder (which is accessible by everybody who know the full URL)
So, I would like to know how I can display the images without storing them on the website (which will fix my URL problem).
My idea was to move the files on the FTP server, and when a users logon and request a page with those images, download them through a FTP connection, save them on the website, display the images, and remove them. Which would make them accessible only between the downloading time. But this solutions sounds REALLY bad to me.
You need always to have a place where your images are stored. But, if you don't want to give a user the chance to know where are stored, you can create a system which is used to show the images.
Think about this, if you want to download a file from Mega, you can't access to the URL where the file is stored, instead of that, the server itselfs calls a system who assign you a "key" and you can download the file only through that system using your "key".
You could use a system like "base64" so you can encode your image, and show it using it, or, you can use the "header" modifier so, you can display an image using a PHP code.
For example your image tag will be like:
<img src="processImage.php?id=01&user=10&key=123" />
So, your processImage will return a "tricky" image, actually not the image, but the code processed by PHP will be returned, like using "imagejpg()" function with the header "Content-Type:image/jpeg" and then the user will not know where the image is stored actually but the img will works actually.
Setting up a live image stream on a website, using images from a webcam. Trying to work out the implementation of it. The webcam takes a picture and requires a crop, resize and upload (not necessarily in that order), before it is displayed to the user, with a new image every minute. Currently I have a php script that does the cropping and resizing, while a webcam program automates the picture taking and uploading. However...
Uploading directly over the existing image causes an issue if the user reloads the page while the upload is taking place, resulting in a missing image.
Uploading with a different filename, then renaming it causes an issue if the user reloads the page during the renaming, resulting in a combination of both images.
Using a sequential filename system then gets tricky with the webpage requiring to know the new upcoming file every minute, along with a potential backlog of images.
Any suggestions are appreciated. Hopefully I'm missing something simple.
Thanks.
Just upload your image with different name, set the current image name somewhere, either in config file or MySQL, and after upload change it.
I've found several answers to this question, but each case was different from mine. Before I spend hours implementing what I think will work, I'd like to get an opinion or two. Who knows, there may be an easier solution that will benefit someone else too!
I'm in the process of creating a website which provides a photo modification service. Each of my customers will be uploading their photos using a modified version of a jQuery/PHP upload script I found on Github (BlueImp's File Upload script- props BlueImp!) When each image is done uploading, a thumbnail of the image is displayed next to the image's filename.
The upload page creates a folder based on their Order #, and a thumbnail subfolder where the images are stored. For example, for Order # 12345:
/uploads/12345 <- Folder where the uploaded images will go
/uploads/12345/thumbs <- Folder where thumbnails will be served from
It's important that clients don't access other clients' photos. I moved the uploads folder outside of my website root, but then the thumbnails weren't displaying when the images finished uploading because, well, they weren't in the website root so the links weren't working.
Here's a solution I thought of:
Separate the folders. Move the main upload folder outside of the document root, but leave the thumbnail folder inside the doc root, so the thumbnails can be served up when each upload completes. When the user has finished uploading their images, delete the thumbnail folder corresponding to that Order #.
Is there a better way to do it? My concern is preventing access to photos (A client will only have to upload them once, then wait for us to finish the modifications. They will NOT have to log back in to download them.) I don't want someone to be able to access the upload folder via the address bar or anywhere else. Can I use an .htaccess file to restrict access, but still allow for linking to the thumbnail images via the upload script?
I apologize for the wordy question. I tried to be as succinct as my limited knowledge of programming would allow. Thank you in advance for your time and effort in helping with this.
two way around
Write a blank index.html on each directory, which will prohibit to access files.
Write below in .htaccess ( if not exist then create this file )
Options -Indexes
OR If you want NO ENTRY outside of the LAN
# no nasty crackers in here!
order deny,allow
deny from all
allow from 192.168.0.0/24
# this would do the same thing..
#allow from 192.168.0.0 to 192.168.0.24
Reference
One more
You want to show the thumbs to each owner customers but not to others?
knowing the Order number (is sequenziell) you can easily try some links and see some photos.
I suggest to use a .htaccess to password the upload folder and to generate a hash number for every thumb that you have to attribute to the order number.
A second solution: password with a .htaccess the upload folder and generate a thumb when you generate the order confirmation page without saving the thumb. (he has to see it only once as you mention).
have fun!
Two things that you should do are:
Disable directory indexing.
Always keep the file names random. Map them using the database. i.e file1.jpg->file_af324234324324ff . You can also store the thumbnail file information in the same table.
just can't get my head around this.
I just finished my own WYSIWYG editor. It allows my users to upload images to embed in their article they are writing.
But how can i keep track of those user uploads ? I want them to be attached to the article, so that when i remove an article all images will also be removed. (keep my disk clean)
My first bet was to add an hidden input field to the article form for every uploaded image containing the image name, then on submit move all attached images from the tmp dir to the article image dir.
But this way a user can attach 100 times a picture to an article, remove them 99 times from the WYSIWYG editor and use only 1. Now i would have to save all the unused images. This seems like waste to me.
Any best practices on this ?
Don't worry about the edge case. Nobody is going to upload then deassociate 99 images.
You have to move the received files out of the tmp dir as soon as the (ajax?) upload sends them over. You cannot wait till the article submission, because the /tmp files would be gone by then.
Try to save your images with enumerated filenames like ArticleName.1.jpeg. And let your WYSIWIG editor inject uniqure placeholder tokens like {{img1}} on which you can see which images are factuall still in the article. (You can also try to deduce the file ids out from <img src="upl/articlename.1.jpeg"... since your WYSIWIG editor generates HTML.)
Anyway, on upload compare the list of enumerated {{img123}} tokens with the existing list of files.123.jpeg. Remove the unused.
Alternative: Do not remove unused images. Sell it as feature, since you now have more article history. And I guess the filesizes are negligible for most web sites.