In my uploading user's avatar scenario, I change users picture extension to jpg. Is this making the browsers to act differently? Is it prone to error for browsers when they read users avatar? Moreover, does it make my web app more secure when an attacker upload a php file?
When you are uploading files you should insure that the file extension is one that you approve, other wise known as a white list approach. You shouldn't rename every extension to .jpeg, this will cause problems. Most HTTPD's will set the mime type based on the file extension, which informs the browser of how to decode the content.
There is another problem with file uploads. Apache will "fall back" on the 2nd file extension if it doesn't have a mime type for the first file extension. So by default,
Even if the user is uploading a valid image it can still cause problems for security. For instance, the images metadata could contain a php tag, which is useful in turning a simple Local File Include vulnerability into remote code execution.
As @Rook said you shouldn't change the extension as it will cause problems. He also pointed out that the metadata could contain malicious data, which is very true. So here are the steps you should follow, roughly:
In the event that any of the above checks fail you just stop the process and delete the file and return a simple error message explaining that the image is no good.
(1) Never use any part of a user-submitted filename in your stored filename. Sanitising a filename is a treacherous job, not as easy to do reliably as it looks at all—especially if your app might end up running on a Windows as well as Linux server.
Store it as something like
If you need to present a ‘friendly’ name to the end browser, use a rewrite so that you can serve it as
(2) Ensure you store the files in a separate directory that contains nothing else. This directory should be the only one the web script user has write access to. It should have locked-down permissions so only static files can be served from it. On Apache this should be done from a higher-level
For this reason, you should consider any user-uploaded-file repository to be compromised for cross-site-scripting, and mitigate this by serving all your user-uploaded files from a different domain. That way any injected script won't be able to cross-site-script into your main web site. Ensure that there is no way to access to user-uploaded resources from your main web site.
The separate site for user resources can be a completely different domain, or it can be a subdomain. But if it's a subdomain you must ensure that there is nothing on the parent domain: so if you serve user resources from