PHP owner based file access protection - file-upload

User uploads files, lets say image files on the remote server.
For example if user1 uploads an image to this path
http://somedomain.com/uploads/123.jpg
And I display image on the web page for the logged in user using the above url.
Suppose the user logs out. and some user come to know about the above url and he can access the image. How can I prevent this?

I will just demonstrate an idea for you. Then you can search in more detail for a solution. There are many solutions, many of them complicated, so it depends on how far you are willing to go. I think this one is a pretty simple solution (depends on your programming skills of course). So,
User clicks the link http://somedomain.com/uploads/123.jpg to open the image.
You have an htaccess file, that will take that url and do a conversion (behind the scenes).
That htaccess file will actually call, for example, the images.php file.
images.php file will get the name of the image and will check if a user is logged in or not.
If user is logged in, it will grub the image file with name, let's say, up-image-123.jpg
The htaccess file will do the conversion again and instead of revealing the real name up-image-123.jpg, will reveal the 123.jpg (which is not a real file name for someone else to access)

Related

Is it possible for others to find images on my server that aren't referenced on my website?

If I upload a file to my webserver, is it possible for anyone or any crawler of some sort to find that file even though I haven't linked to it from anywhere or referenced to it?
Say for example you have a site that hides content to non logged in users, if I know the path to an image file I am able to reach that file even though I am not logged in. This is the case of several sites I regularly visit. But is this really a problem, is it possible for people with bad intentions to find these images even though they can't log in?
My next question would of course be (maybe that's another thread though): how can I as a web developer, using a LAMP stack, protect file paths from being requested from non logged in users?

Hiding/changing the virtual path in classic ASP

We have a website that requires a username and password. Once logged in, the user can select a link to a PDF in the web browser. Once this has happened they are able to see the full URL path of the PDF, they could copy and paste the path into a different browser without logging in, or send the address to someone else to look at.
I am asking this for a co-worker so I am not too sure on what is needed, but they want to change it from say "documents/customerlist.pdf" to "documents/info.asp" (not sure what the file type should be, maybe just "documents/info"?) I think that is what the goal is. Is this possible? If someone could point me in the right direction we might be able to figure it out!
I should think you can do this in ASP. You'll need to deliver the PDF dynamically via an ASP page, which detects the user's session and only serves the data if they are suitably authenticated (so copying the URL to a different browser/machine will result in a 404 or access denied, as you wish). You'll need to read the data from file and binary-write it to the browser, and set HTTP headers for mime-type, content length etc.
I'd start off with serving it on a pdf.asp?file=customerlist URL, but you can later experiment with changing this to something more readable (docs/customerlist.php). You'll need to look into URL rewriting here.
So, that's the general approach. If you do a web-search around these topics ("ASP serve binary file", "ASP URL rewriting") you are sure to get plenty of examples.

How to check if user selected file(s) my Sandboxed app has permission to write?

I'm enabling sandboxing in my OS X app to resubmit to the app store and I'm trying to find the most elegant way to make sure the user can only select resources my app has permissions to change.
Stripped down scenario:
user selects a picture on the file system via an NSOpenPanel
user clicks the Process Picture button on the app
app retrieves information from the internet
app alters the picture's metadata.
After the user is done selecting the pictures, I want to make sure each one is located under the Pictures folder otherwise my write to the physical file will simply silently fail.
Apple recommends the following to determine the Pictures folder's location:
The Pictures directory contains the user’s images and photos. To get
the path to this directory use the NSPicturesDirectory search path key
with the NSUserDomainMask domain.
Implementing the above gives me a path that looks like this:
/Users/thomas/Library/Containers/com.blazingfrog.latipics/Data/Pictures/picture1.jpg
But when I want to see what pictures the user selected,[myOpenPanel URLs] returns /Users/thomas/Pictures/picture1.jpg
These two paths are logically identical but look very different. How can I compare them in way that works every time?
In case it helps, to prepare my app for sandboxing I did the following
enabled Entitlements in XCode
enabled App Sandboxing
enabled File System (Read)
enabled allowing Incoming/Outgoing Network Connections
enabled Pictures Folder access (Read/Write)
You should almost never fail silently. If something goes wrong, report it to the user, as best you can. This is exactly what NSError is designed for.
You should almost never attempt to figure out if an operation will succeed before trying it. Doing so leaves you open to race conditions. Instead go ahead and try the operation; if it fails, handle that gracefully.
It sounds like you actually want the com.apple.security.files.user-selected.read-write entitlement. This will give you write access to any files the user selects using an open panel.
[[NSFileManager defaultManager] isWritableFileAtPath:path]

remote image embeds: how to handle ones that require authentication?

I manage a large and active forum and we're being plagued by a very serious problem. We allow users to embed remote images, much like how stackoverflow handles image (imgur) however we don't have a specific set of hosts, images can be embedded from any host with the following code:
[img]http://randomsource.org/image.png[/img]
and this works fine and dandy... except users can embed an image that require authentication, the image causes a pop-up to appear and because authentication pop-ups can be edited they put something like "please enter your [sitename] username and password here" and unfortunately our users have been falling for it.
What is the correct response to this? I have been considering the following:
Each page load has a piece of Javascript execute that checks each image on the page and its status
Have an authorised list of image hosts
Disable remote embedding completely
The problem is I've NEVER seen this happen anywhere else, yet we're plagued with it, how do we prevent this?
Its more than the password problem. You are also allowing some of your users to carry out CSRF attacks against other users. For example, a user can set up his profile image as [img]http://my-active-forum.com/some-dangerous-operation?with-some-parameters[/img].
The best solution is to -
Download the image server side and store it on the file system/database. Keep a reasonable maximum file size, otherwise the attacker can download tons of GBs of data onto your servers to hog n/w and disk resources.
Optionally, verify the file is actually an image
Serve the image using a throw-away domain or ip address. It is possible to create images that masquerade as a jar or applet; serving all files from a throwaway domain protects you
from such malicious activity.
If you cannot download the images on the server side, create a white list of allowed url patterns (not just domains) on the server side. Discard any urls that don't match this URL pattern.
You MUST NOT perform any checks in javascript. Performing checks in JS solves your immediate problems, but does not protect your from CSRF. You are still making a request to an attacker-controlled url from your users browser, and that is risky. Besides, the performance impact of that approach is prohibitive.
I think you mostly answered your own question. Personally I would have gone for a mix between option 1 and option 2: i.e. create a client-side Javascript which first checks image embed URLs against a set of white-listed hosts. For each embedded URL which is not in that list, do something along these lines, while checking that the server does not return the 401 status code.
This way there is a balance between latency (we attempt to minimize duplicate requests via the HEAD method and domain whitelists) and security.
Having said that, option 2 is the safest one, if your users can accept it.

How do I implement a secure upload/download area?

I've been asked to create a solution where people log in and are able to upload and download off of our work server. So John uploads a photo, and Jen can download it, for example. They also have to authenticate themselves.
Can someone give me a rough overview of how to implement this? I'm familiar enough with MySQL, C#, and JavaScript.
The rough overview
This should just be a matter of planning out the pieces.
at the very top of the page, put some code that checks if a user is logged in. If not, show a login form (or redirect to...). If they are logged in, show the rest of the page. If not, you'll need some logic to show a form, and then check it once it's submitted for authentication, and set a SESSION cookie or something similar.
Once the user is logged in, on the homepage, you might have an file-upload form and a listing of existing files. How you would style would depend on how many files you might expect to have. To keep things extremely simple, you could simple iterate through whatever files are in the upload directory. If you expect many more files than that, you may consider using a db.
Handle a file upload by sanitizing filenames (checking for filetype/filesize if you want to limit those) and putting the file into the directory.
Force the users to download the files (instead of having the browser decide what to do with them) for security purposes. Implementing this on certain filetypes may also be acceptable.
Other thoughts
You probably would not want the users to be able to excecute any files, so keeping the file directory hidden would be a good idea.
Keeping track of who uploaded and downloaded what is also doable, but would add another layer of complication to the script.