The bottom line is this, if users can upload something to your site, and then your site will show that thing to other users before you have a chance to figure out if its a problem, then your site will be exploited by bad actors.
For a long time an out of the box server installation would include anonymous ftp access. Of course nothing is quite so attractive as a 'free' place to dump and retrieve stuff. It was kind of like setting up a warez/malware camera trap.
and then your site will show that thing to other users
I think this is worth emphasizing more than the article does. The problem is just as much with the after-the-fact direct access as with the upload. Given the wide variety of illegal things you will quickly end up hosting and the amount of traffic this will generate, cross site scripting attacks may not be your top concern.
Even if it does not show anything to other users, just having the wrong extension can already bite you badly.
Uploading php files instead of images has been used to gain access to machines. Anything that gets stored as a file on the filesystem of the destination machine is a huge risk. All it takes is one little misconfiguration somewhere else and you're wide open.
Not to mention that many Apache configurations will use mod_mime, which by default enables multiple extensions.
So if someone uploads a file called `image.php.jpg`, the file is executed by Apache as PHP code. And obviously verifying the MIME type or even the content of the file won't help you here, since you can just write a JPEG header and then throw in `<?php system("..."); ?>` after it.
Even when you think you're safe based on what you'd consider to be obvious assumptions ("the file extension is whatever comes up after the last period"), there are weird things like this that might bite you.
This is only if you subsequently give them a link to what they uploaded, correct?
I have a site that allows uploads (students turning in Java files) but the files are just stored in a folder on the server that isn't in the web-served path. They can't see the file again once uploaded. I assume (and I think rightly) that there's no security risk in my case.
It depends on the kind of application, but for the most part you are right. If a file is saved to a path that is not part of the "web root", then it is unlikely that any vulnerabilities will be introduced.
Just make sure it is a hardcoded path, and not one that users can manipulate in any way (a filename of "../../../../file.java" for example). And if there is some other interface that reads files from that directory and outputs them to a page, that will also need to be secured against XSS.
Are these exceedingly simple programs 10 line programs? Otherwise:
How do you know they compile?
How do you know they work?
How do you know they handle all the edge cases you can throw at them.
If you have a 100% accurate parser and compiler in your head, I am impressed.
Our teachers (and this was 15 years ago) had test-runners which would compile and run our programs to make sure they met the requirements of the homework THEN they looked at the code and marked it for style etc.
Sometimes they provided these test runners to us so we could check them ourselves, sometimes they didn't (this was, naturally, harder).
Obviously such workflow, while being fairer, requires a reliable sandbox of some kind—even though one might argue that in a university such things may be of less importance and that allowing for some degree of hacking is educational and perhaps should even be tacitly encouraged, still you'd want to make sure that when students break your system they can't go Bobby Tables on it or dump everyone's private data on black market.
As the article explains, the problem is that SWF files hosted on one domain can execute in the security context of that domain, even when embedded in a page on a completely different site. So allowing attacker-controlled uploads makes any credentials on that domain, such as session cookies and CSRF tokens, vulnerable. If the SWF is hosted on a domain with no sensitive credentials, this particular problem goes away.
The Symantec article is interesting but only says the fake page is hosted on "Google's servers", not "google.com", but users might believe "googledrive.com" is trustworthy.
Browser security relies on the "same origin policy" which says that certain operations are restricted to only access resources in the same domain as the active page. In particular, you can't read cookies from another domain, and you can't read the responses of authenticated HTTP requests. XSS and CSRF attacks all rely on an circumventing this protection in various ways.
In this case, Flash considers the origin to be the location of the SWF file. This is different from normal JavaScript where all scripts in a page run under that page's origin, no matter where they're loaded from.
It depends on the attack you're trying to prevent against.
The blog post in the OP solely discusses XSS vulnerabilities that are introduced by unrestricted file uploads. There are numerous other issues that can occur from arbitrary file uploads (malware hosting, arbitrary code execution if it's PHP, phishing), but to prevent against a user content ever reaching sensitive data via XSS, placing all user data on a separate domain is pretty much your best bet.
header mean you can no longer display the image in your service? Won't browsers treat it as a file download? Most services that allow image uploads do so because the images will get displayed on a page? (that's what I do)
Most services seem to be moving file uploads to S3 (or similar services) these days, so I'm not sure this advice is really helpful. To take that a step further, my preference now is to upload directly to S3 and bypass my app server altogether. At least in Rails, it's fairly easy to setup.
Problem is that many tend to use S3 but bind a subdomain to it. S3 does not validate the content of those files, so combined with a [wildcard].domain.com crossdomain.xml and you're still as vulnerable as per above.
Some also restricts so that different filetypes on S3 will be served as Inline content, but that will just save you from XSS, and not the CSRF leakage. It's still suprisingly common with a crossdomain.xml restricted to [wildcard].domain.com.
> So if you allow file uploads or printing arbitrary user data in your service, you should always verify the contents as well as sending a Content-Disposition header where applicable.
The idea that you can "verify the contents" is pretty much just wrong. You actually have to parse the files and write out your own known-safe version. It's a real pain in the butt to do that correctly and securely across a wide variety of file types.
Even parsing arbitrary user uploads with something like ImageMagick is probably exploitable, simply because those libraries weren't designed to handle hostile input.
This isn't too related to what the blog post was discussing, but just to give an example of how you're right:
If a PHP page is allowing file uploads and only verifies the content of the data, but nothing else, then no protection is offered against arbitrary code execution. It's easy to craft a JPEG header and then place `<?php ... ?>` right after it; you could even append it to a valid JPEG body, too.
Isn't it a reasonable workaround to scan the file for content-type and make the file available once it passes the criteria for the upload? Find a php file uploaded with an extension of .jpg? "Sorry, there was a problem with your file. Please try again."
For a long time an out of the box server installation would include anonymous ftp access. Of course nothing is quite so attractive as a 'free' place to dump and retrieve stuff. It was kind of like setting up a warez/malware camera trap.