Determining file type
-
In my web applications, users will be allowed to upload their image files to the server. How can I determine the type of images to prevent them from uploading non-image files?
Assuming the client (web browser, other HTTP client application) set the Content-Type for the request, you can use
HttpRequest.ContentType
to check for common MIME-types like "image/gif", "image/jpeg", "image/png", "image/x-png", "image/bmp", and probably a few others you might be interested in avoiding. DO NOT rely on the extensions, though. When it comes to the web (among other things) the Content-Type is all that matters (web servers typically are configured to default to certain MIME-types based on file extensions, but this can be changed ad-hoc).-----BEGIN GEEK CODE BLOCK----- Version: 3.21 GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++ -----END GEEK CODE BLOCK-----
-
Assuming the client (web browser, other HTTP client application) set the Content-Type for the request, you can use
HttpRequest.ContentType
to check for common MIME-types like "image/gif", "image/jpeg", "image/png", "image/x-png", "image/bmp", and probably a few others you might be interested in avoiding. DO NOT rely on the extensions, though. When it comes to the web (among other things) the Content-Type is all that matters (web servers typically are configured to default to certain MIME-types based on file extensions, but this can be changed ad-hoc).-----BEGIN GEEK CODE BLOCK----- Version: 3.21 GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++ -----END GEEK CODE BLOCK-----
It would be HttpRequest.Files["foo"].ContentType that he should check, assuming we are talking about standard upload with an <input name='foo' type='file'> tag. IE does set this ContentType header (which isn't an HTTP header, it's a MIME header in one of the body parts of the content) but it seems unwise to rely on that. I would suggest something like:
bool IsBitmap(string tagName) {
try {
using (Bitmap b = new Bitmap(HttpRequest.Files[tagName].InputStream));
} catch {
return false;
}
return true;
}Alternatively, if you don't want to pay the cost of parsing the whole image, you could just look at the first few bytes. All of the likely image types have easy to parse signatures in the header. A quick glance at each spec will give you the details. -Blake
-
It would be HttpRequest.Files["foo"].ContentType that he should check, assuming we are talking about standard upload with an <input name='foo' type='file'> tag. IE does set this ContentType header (which isn't an HTTP header, it's a MIME header in one of the body parts of the content) but it seems unwise to rely on that. I would suggest something like:
bool IsBitmap(string tagName) {
try {
using (Bitmap b = new Bitmap(HttpRequest.Files[tagName].InputStream));
} catch {
return false;
}
return true;
}Alternatively, if you don't want to pay the cost of parsing the whole image, you could just look at the first few bytes. All of the likely image types have easy to parse signatures in the header. A quick glance at each spec will give you the details. -Blake
I hate to burst your bubble, but while you are correct about using the
Files
property as being "standard" (which there is no "correct" way), I am also right. RTFD, or know from experience like I do, which is also based on reading the RFCs.HttpRequest.Files
is valid for "multipart/form-data" in which case each part contains it's own Content-Type MIME header. But, if I send a single file to the server in another way (as the file data itself), I use the Content-Type HTTP header, just like theHttpResponse
sends to the client with practically every response. It just depends on how you send the file. Browsers will default to sending files that way (along with the other form data, hence the MIME type) but other clients (and browsers through scripting or browser-specific technology) can send files as the encoded data (usually base64, but not restricted to it) of the proper MIME type using the HTTP Content-Type header.-----BEGIN GEEK CODE BLOCK----- Version: 3.21 GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++ -----END GEEK CODE BLOCK-----
-
I hate to burst your bubble, but while you are correct about using the
Files
property as being "standard" (which there is no "correct" way), I am also right. RTFD, or know from experience like I do, which is also based on reading the RFCs.HttpRequest.Files
is valid for "multipart/form-data" in which case each part contains it's own Content-Type MIME header. But, if I send a single file to the server in another way (as the file data itself), I use the Content-Type HTTP header, just like theHttpResponse
sends to the client with practically every response. It just depends on how you send the file. Browsers will default to sending files that way (along with the other form data, hence the MIME type) but other clients (and browsers through scripting or browser-specific technology) can send files as the encoded data (usually base64, but not restricted to it) of the proper MIME type using the HTTP Content-Type header.-----BEGIN GEEK CODE BLOCK----- Version: 3.21 GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++ -----END GEEK CODE BLOCK-----
Heath Stewart wrote: I hate to burst your bubble, but while you are correct about using the Files property as being "standard" (which there is no "correct" way), I am also right. Now now Heath, that sort of hostility is unnecessary. The very first line of my message said "assuming we are talking about standard upload with an <input name='foo' type='file'> tag". Since the original poster didn't specify any custom client software it is a very safe assumption he is just using the browser and and HTML form to upload with. The fact is, your answer was wrong for the most common way to upload files. Heath Stewart wrote: RTFD, or know from experience like I do, which is also based on reading the RFCs. I am intimately familar with the RFCs, thank you, and have written code that does this many times, starting back when I had to write my own ISAPI to handle the data. Heath Stewart wrote: It just depends on how you send the file. *chuckles* Right... which translates as, as long as you write code to ensure you set the Content-Type header correctly on the client, then you can depend on checking it on the server. But you failed to mention that in your answer, didn't you? Quick Quiz: if you use System.Net.WebClient.UploadFile(), does it sniff the data and set your Content-Type header correctly? How about MSXML2.XMLHTTP.4.0? Looks like you've just moved his problem to the client code instead of the server code and not helped him at all. -Blake
-
Heath Stewart wrote: I hate to burst your bubble, but while you are correct about using the Files property as being "standard" (which there is no "correct" way), I am also right. Now now Heath, that sort of hostility is unnecessary. The very first line of my message said "assuming we are talking about standard upload with an <input name='foo' type='file'> tag". Since the original poster didn't specify any custom client software it is a very safe assumption he is just using the browser and and HTML form to upload with. The fact is, your answer was wrong for the most common way to upload files. Heath Stewart wrote: RTFD, or know from experience like I do, which is also based on reading the RFCs. I am intimately familar with the RFCs, thank you, and have written code that does this many times, starting back when I had to write my own ISAPI to handle the data. Heath Stewart wrote: It just depends on how you send the file. *chuckles* Right... which translates as, as long as you write code to ensure you set the Content-Type header correctly on the client, then you can depend on checking it on the server. But you failed to mention that in your answer, didn't you? Quick Quiz: if you use System.Net.WebClient.UploadFile(), does it sniff the data and set your Content-Type header correctly? How about MSXML2.XMLHTTP.4.0? Looks like you've just moved his problem to the client code instead of the server code and not helped him at all. -Blake
Blake Coverett wrote: Now now Heath, that sort of hostility is unnecessary. Tsk, tsk, tsk. Are you actively trying to look more stupid here? class MarkIsEvenMoreStupidThanIThought Pratice what you preach Blake.
-
Blake Coverett wrote: Now now Heath, that sort of hostility is unnecessary. Tsk, tsk, tsk. Are you actively trying to look more stupid here? class MarkIsEvenMoreStupidThanIThought Pratice what you preach Blake.
Mark Nischalke wrote: Pratice what you preach Blake. But you forgot to quote the rest of what I said in that post, Mark. Blake Coverett wrote: I don't have a problem with people who don't know things, after all there's lots I don't know, but I have no tolerance for aggressively stupid people who won't learn when taught. If the shoe fits, wear it. -Blake