업로드 된 파일의 MIME 유형은 브라우저에서 어떻게 결정됩니까?


87

사용자가 .zip 파일을 업로드해야하는 웹 앱이 있습니다. 서버 측에서 업로드 된 파일의 MIME 유형을 확인하여 application/x-zip-compressed또는 application/zip.

이것은 Firefox와 IE에서 잘 작동했습니다. 그러나 동료가 테스트했을 때 Firefox에서는 실패했지만 (보낸 MIME 유형은 " application/octet-stream" 와 같음 ) Internet Explorer에서 작업했습니다. 모든 추가 기능이 비활성화 된 IE8, FF 3.5.1, Win XP SP3, WinRAR이 기본 .zip 파일 처리기로 설치되어 있습니다 (관련성이 있는지 확실하지 않음).

그래서 내 질문은 브라우저가 보낼 MIME 유형을 어떻게 결정합니까?

참고 : MIME 유형이 브라우저에서 전송되어 신뢰할 수 없다는 것을 알고 있습니다. 나는 단지 편의상 확인하고 있습니다. 주로 zip 파일이 아닌 파일을 zip 파일로 열려고 시도하여 얻는 것보다 더 친숙한 오류 메시지를 제공하고 (아마도 무거운) zip 파일 라이브러리를로드하지 않도록합니다.


application / octet-stream은 바이너리 파일을 지정합니다. zip 파일인지 확인하려면 파일 확장자를 가져올 수 있어야합니다. 명확히하기 위해 FF에서는 효과가 있었지만 동료는 그렇지 않았나요?
Kevin Crowell

네, 두 브라우저 모두에서 저에게
효과적

에서 살펴 input/@formenctype또는 form/@enctype속성
tuxSlayer

답변:


72

크롬

Chrome (작성 당시 버전 38) 에는 MIME 유형을 결정하는 세 가지 방법이 있으며 특정 순서로 수행합니다. 아래 스 니펫은 file src/net/base/mime_util.cc, method 에서 가져온 것 MimeUtil::GetMimeTypeFromExtensionHelper입니다.

// We implement the same algorithm as Mozilla for mapping a file extension to
// a mime type.  That is, we first check a hard-coded list (that cannot be
// overridden), and then if not found there, we defer to the system registry.
// Finally, we scan a secondary hard-coded list to catch types that we can
// deduce but that we also want to allow the OS to override.

하드 코딩 된 목록은 https://cs.chromium.org/chromium/src/net/base/mime_util.cc?l=170 ( kPrimaryMappingskSecondaryMappings) 파일에서 조금 더 앞서 있습니다.

예 : Microsoft Excel이 설치된 Windows 시스템에서 CSV 파일을 업로드 할 때 Chrome은이를 application/vnd.ms-excel. 이는 .csv첫 번째 하드 코딩 된 목록에 지정되지 않았기 때문에 브라우저가 시스템 레지스트리로 돌아갑니다. 로 설정된 HKEY_CLASSES_ROOT\.csvContent Typeapplication/vnd.ms-excel있습니다.

인터넷 익스플로러

다시 동일한 예제를 사용하면 브라우저가 application/vnd.ms-excel. Internet Explorer (작성 당시 버전 11) 가 레지스트리를 사용 한다고 가정하는 것이 합리적이라고 생각합니다 . 아마도 Chrome 및 Firefox와 같은 하드 코딩 된 목록을 사용하지만, 폐쇄 된 소스 특성으로 인해 확인하기가 어렵습니다.

Firefox

Chrome 코드에서 알 수 있듯이 Firefox (작성 당시 버전 32) 는 비슷한 방식으로 작동합니다. 파일의 스 니펫 uriloader\exthandler\nsExternalHelperAppService.cpp, 메소드nsExternalHelperAppService::GetTypeFromExtension

// OK. We want to try the following sources of mimetype information, in this order:
// 1. defaultMimeEntries array
// 2. User-set preferences (managed by the handler service)
// 3. OS-provided information
// 4. our "extras" array
// 5. Information from plugins
// 6. The "ext-to-type-mapping" category

하드 코딩 된 목록은 파일의 앞부분 인 441 줄 근처에 있습니다. defaultMimeEntriesextraMimeEntries.

내 현재 프로필을 사용하면 (위 목록의 항목 2)에 항목 text/csv이 있으므로 브라우저 가보고합니다 mimeTypes.rdf. 이 항목이없는 새 프로필을 사용하면 브라우저가보고합니다 application/vnd.ms-excel(목록의 항목 3).

요약

브라우저의 하드 코딩 된 목록은 매우 제한적입니다. 종종 브라우저에서 보낸 MIME 유형은 OS에서보고하는 유형입니다. 이것이 바로 질문에서 언급했듯이 브라우저에서보고하는 MIME 유형이 신뢰할 수없는 이유입니다.


1
감사! 크롬 소스에 하드 코딩 된 목록에 대한 링크가 있습니까?
Kip

@Kip 네, 링크를 추가했습니다. 파이어 폭스는 (공식적인) 온라인 소스 코드 브라우저가없는 것 같습니다. 저는 그들의 FTP 서버에서 다운로드해야했습니다.
user247702

MIME를 CSV 용 ms-excel로 사용하는 것은 성가신 일입니다. 왜 하드 코딩 된 목록에 없는지 궁금합니다.
Kris

마임 타입 검출 일부 업데이트는 2014 년부터이 있다면 알고 좋은 것입니다
비탈리 Isaev

1
@VitalyIsaev이 이후 변경되지 않았 음을 크롬 코드 쇼에서 얼핏 2014
user247702

12

Kip, RFC, MSDN 및 MDN을 읽는 데 시간을 보냈습니다. 여기 내가 이해할 수있는 것이 있습니다. 브라우저가 업로드 할 파일을 발견하면 수신 한 데이터의 첫 번째 버퍼를 확인한 다음 이에 대한 테스트를 실행합니다. 이러한 테스트는 파일이 알려진 MIME 유형인지 아닌지 확인하려고 시도하고 알려진 MIME 유형 인 경우 알려진 MIME 유형에 대해 추가로 테스트하고 그에 따라 조치를 취합니다. IE는 확장에서 파일 유형을 결정하는 것보다 먼저 이것을 시도한다고 생각합니다. 이 페이지에서는 IE http://msdn.microsoft.com/en-us/library/ms775147%28v=vs.85%29.aspx에 대해 설명합니다 . 파이어 폭스의 경우 파일 시스템 또는 디렉토리 항목에서 파일 정보를 읽은 다음 파일 유형을 결정한다는 것을 이해할 수있었습니다. 다음은 FF https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIFile에 대한 링크입니다.. 나는 이것에 대해 더 권위있는 정보를 여전히 갖고 싶습니다.


8

이것은 아마도 OS 및 브라우저에 따라 다를 수 있지만 Windows에서 주어진 파일 확장자에 대한 MIME 유형은 HKCR 아래의 레지스트리에서 찾을 수 있습니다.

예를 들면 :

HKEY_CLASSES_ROOT.zip-ContentType

MIME에서 파일 확장자로 이동하려면 아래의 키를 볼 수 있습니다.

HKEY_CLASSES_ROOT \ Mime \ Database \ Content Type

특정 MIME 유형에 대한 기본 확장자를 가져옵니다.


감사. 안타깝게도 저와 제 동료 모두 레지스트리에서 올바른 것으로 보입니다. 나는 그것이 그를 위해 IE에서 작동했던 이유라고 생각한다. 그러나 FF는 그것을 어떻게 든 다르게 얻는다 ... 오 잘 :(
Kip

5

이것은 귀하의 질문에 대한 답은 아니지만 해결하려는 문제를 해결합니다. YMMV.

당신이 쓴 것처럼, 각 브라우저는 그것을 결정하는 방법이 있기 때문에 MIME 유형은 신뢰할 수 없습니다. 그러나 브라우저는 파일의 원래 이름 (확장자 포함)을 보냅니다. 따라서 문제를 처리하는 가장 좋은 방법은 MIME 유형 대신 파일의 확장자를 검사하는 것입니다.

여전히 mime 유형이 필요한 경우 자체 아파치의 mime.types를 사용하여 서버 측을 결정할 수 있습니다.


1
자세히 설명 하시겠습니까? 내 경험상 브라우저는 항상 올바른 원래 파일 이름 (확장자 포함)을 보내지 만 MIME 유형은 크게 다릅니다. 그렇습니다. 훨씬 더 신뢰할 수 있습니다.
johndodo

옳은. 최종 사용자는 실제 유형에 관계없이 모든 확장을 넣을 수 있으므로 신뢰할 수 없다는 것을 의미했습니다.
Djizeus

사실이지만 확장 또는 MIME 유형을 사용하는지 여부는 중요하지 않습니다. 사용자가 제공 한 입력을 신뢰해서는 안됩니다. 그러나 OP는 그가이 문제를 알고 있다고 명시 적으로 말 했으므로 이것은이 질문의 일부가 아닙니다. Btw, 당신이 반대표를 제거해 주시면 감사하겠습니다.
johndodo

당신 말이 맞아요, 질문에 신경 쓰지 않았어요. 내 투표를 취소 할 수 있지만 답변을 편집해야합니다 (시스템에 의해 시행됨) ...
Djizeus

네, 나는 johndodo에 동의합니다. Stijn이 위의 답변에서 설명했듯이 Chrome과 Firefox는 먼저 확장 프로그램을 확인합니다. 그들은 결국 같은 일을하고 있습니다.
Jenix

0

저는 johndodo에 동의합니다. 브라우저에서 보낸 MIME 유형을 신뢰할 수 없게 만드는 변수가 너무 많습니다. 받은 하위 유형을 제외하고 '응용 프로그램'과 같은 유형에만 집중합니다. 앱이 PHP 기반 인 경우 explode () 함수를 사용하여 쉽게 수행 할 수 있습니다. 또한 파일 확장자를 확인하여 .zip 또는 원하는 다른 압축인지 확인하십시오!


0

에 따르면 RFC1867 - HTML에서 양식 기반 파일 업로드 :

미디어 유형이 알려진 경우 (예 : 파일 확장자 또는 운영 체제 입력 정보에서 유추) 또는 응용 프로그램 / 옥텟 스트림으로 각 부분에 적절한 콘텐츠 유형으로 레이블을 지정해야합니다.

그래서 내 이해는 유형을 추론 할 수없는 경우 application/octet-stream일종의 blanket catch-all식별자 와 같습니다 .


예,이 모든 것을 이해합니다. 문제는 브라우저가 어떻게 추론 하는가였습니다.
Kip

그래도 알아볼 가치가 있겠죠? 이것이 application/octet-stream포괄이라면 다른 접근 방식은 추측을 할 수 있다면 브라우저를 신뢰하고 application/octet-stream.
MikeBeaton
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.