요약
- RFC 1806은 MIME에
inline,attachment그리고 선택적 파일 이름을 추가했지만, 이를 명령이나 접수 증명이 아니라 희망하는 표시 방식과 제안된 보관 이름으로 기술했다. - 표시 여부, 저장 위치, 충돌 회피 방법, 안전한 확장자, 이후 열기에 명시적 행동이 필요한지 등 중요한 결정은 수신 에이전트가 그대로 보유했다.
- RFC 2183, RFC 2231, RFC 6266, RFC 7578은 수신자의 파일시스템에 대한 권한을 옮기지 않으면서 이 어휘를 더 풍부한 메타데이터, 국제화된 이름, HTTP 다운로드와 업로드로 확장했다.
MIME은 '다음에 무엇이 일어나야 하는지' 말할 수 있기 전에 이미 부분을 운반할 수 있었다
인터넷 메일은 표시 방식에 대한 합의가 되기 전에 먼저 컨테이너가 되었다.RFC 1521은 하나의 메시지가 형식화된 텍스트, 이미지, 응용 프로그램, 중첩된 멀티파트 구조를 함께 실을 수 있게 했다. 이를 대체한RFC 2045와RFC 2046은 문법과 미디어 타입을 다듬었다. 수신자는 어떤 부분이 자신을 무엇이라 주장하는지, 인코딩된 바이트가 어디서 끝나는지 알아낼 수 있었다.
그러나 그것으로 사람이 무엇을 보아야 하는지 정해지지 않았다. 어떤 메일 프로그램은 읽기 창에서 모든 이미지를 펼쳐 보였다. 다른 프로그램은 파일 목록을 보여주었다. 문자 터미널은 그래픽 워크스테이션을 흉내 낼 수 없었다. 메시지 구조는 재료를 제공할 뿐, 표시는 여전히 수신 측 사용자 에이전트의 몫이었다.
1995년 6월에 실험적(Experimental) 사양으로 발행된RFC 1806은 바로 이 공백을 다루었다. 임의의 MIME 엔티티에 선택적 Content-Disposition 헤더를 도입한 것이다. 발신자는 부분에 희망하는 표시 의미를 태그할 수 있었다. 필드가 없으면 메일 사용자 에이전트는 자신이 적절하다고 판단하는 방식을 자유롭게 선택했다.
이 부재 규칙이 곧 아키텍처를 드러낸다. 헤더는 수신자의 권한을 만들지 않았다. 수신자가 고려할 진술을 하나 더 준 것뿐이다. 화면, 로컬 정책, 파일시스템, 사용자와의 관계는 여전히 수신 프로그램의 손에 있었다. 메시지 안으로 들어온 필드는 그 통제 지점에 영향을 줄 수는 있어도 그것들을 소유할 수 없었다.
두 가지 배치(disposition)가 다음 행동을 할당했다
첫 어휘는 의도적으로 작았다.inline은 본문 부분이 상위 멀티파트의 규칙에 따라 평범한 흐름 안에서 자동으로 표시되어야 한다는 뜻이었다.attachment는 자동 표시가 일어나서는 안 되며, 사용자의 추가 행동이 먼저 와야 한다는 뜻이었다. 그래픽 프로그램은 아이콘을, 텍스트 터미널은 선택 가능한 목록을 보여줄 수 있었다.
이것은 의사결정의 유용한 분배였다. 발신자는 부분이 즉시 문서의 일부인지 별개의 개체인지 알고 있었고, 수신자는 무엇을 안전하게 렌더링할 수 있는지와 자신의 인터페이스 작동 방식을 알고 있었다. attachment라는 관문을 넘을지는 사용자가 결정했다.
그러나 배치 값은 관찰이 아니었다.inline은 클라이언트가 해당 미디어 타입을 지원하고, 안전 검사를 통과하고, 바이트를 렌더링하고, 그것을 사람 앞에 내놓았다는 증거가 아니었다.attachment도 누군가 무엇을 열었거나 저장했다는 증거가 아니었다. 표준을 준수하는 수신자조차 필드와 무관한 이유로 inline 부분을 억제하거나 첨부를 격리할 수 있었다.
중첩된 멀티파트 구조는 한계를 더 선명하게 만들었다. 멀티파트 엔티티의 배치는 컨테이너 전체에 적용된다. 컨테이너가 첨부라면 그 표시는 사용자 행동을 기다린다. 컨테이너가 열린 뒤에야 내부 부분들의 배치가 의미를 가진다. 하나의 메시지가 따라서 여러 겹의 관문을 연달아 담을 수 있었다. 바깥의 어떤 표시도 내부 부분에 도달했음을 증명하지 못했다.
알 수 없는 값은 보수적으로 처리되었다. RFC 1806은 인식되지 않은 배치 타입을 attachment로 다루도록 했는데, 정교한 새 타입을 쓰는 발신자는 대개 평범한 inline 표시 이상을 의도했을 것이라는 논리였다. 인식되지 않은 매개변수는 무시할 수 있었다. 이 폴백은 자동 노출을 제한했을 뿐, 수신자가 이해하지 못하는 토큰에 의미를 부여하지는 않았다.
파일 이름은 네트워크를 건넜지만 네임스페이스 경계는 넘지 않았다
선택적filename매개변수는 RFC 1806이 말한 '기본 보관 배치'를 제공했다. 수신자가 본문 부분을 분리하기로 하면, 그 값은 외부 파일의 이름이 무엇이면 좋을지 제안할 수 있었다.
“제안”이라는 단어가 보안 모델의 대부분을 담고 있었다. 한 시스템에서 무해한 파일 이름이 다른 시스템에서는 경로, 장치, 시작 프로그램 지시 또는 실행 트리거가 될 수 있다. 어떤 이름이 이미 존재하는지, 어떤 디렉터리가 쓰기 가능한지, 어떤 구분자가 의미를 가지는지, 어떤 응용 프로그램이 확장자를 해석하는지 아는 쪽은 발신자가 아니라 수신자다.
그래서 RFC 1806은 디렉터리 정보를 존중해서는 안 된다고 밝혔다. 경로처럼 보이는 값은 마지막 구성 요소로 축소되어야 했다. 수신 프로그램은 기존 파일을 덮어쓰지 않아야 했고, 이름을 로컬 관례에 맞게 조정해야 했다. 이 필드는 inline 엔티티에 붙어도 파일 쓰기를 일으키지 않을 수 있었다. 사용자가 나중에 저장하기로 선택할 때를 위한 이름을 제공할 뿐이었다.
사양의 보안 절은 일반적 경고 뒤로 숨지 않았다. 시작 파일 생성, 시스템 파일 덮어쓰기, 기존 파일 교체, 명령 검색 경로에 실행 파일 놓기, 파이프로 내용 보내기 등 위험을 구체적으로 열거했다. 일반 규칙은, 수신 프로그램이 명시적 사용자 개시 없이 해석이나 실행이 일어나도록 내용의 이름을 붙이거나 위치시켜서는 안 된다는 것이었다.
이것은 축소판 완전한 근거 사슬이다. 발신자가 문자열을 내보냈다. 파서가 그것을 복원했다. 정책이 경로 의미를 제거하고 충돌을 검사했다. 파일시스템 작업이 실제 로컬 이름 아래 바이트를 만들었다. 나중에 응용 프로그램이 그것을 열지도 모른다. 헤더는 첫 번째 주장과, 캡처가 있다면 두 번째 주장만 증명한다. 나머지 사건들에 대한 접수 증명으로 쓸 수는 없다.
표준 트랙 개정판은 이 한계를 유지했다
RFC 1806의 RFC 시리즈 기록에 따르면RFC 2183이 1997년 8월 이 실험을 제안 표준(Proposed Standard)으로 대체했다. 개정판은inline,attachment, 그리고 수신자가 소유하는 파일 이름 검사를 그대로 두었다. 생성·수정·읽기 날짜와 근사 크기가 추가되었다.
이 추가 사항들은 MIME 엔티티를 옮길 수 있는 파일 기록처럼 보이게 했지만, 그 이력을 인증하지는 않았다. RFC 2183은 유닉스와 POSIX 구현자에게st_ctime은 생성 시간이 아니라고 경고까지 했다. 날짜는 발신자가 실어 보낸 주장이었다. 수신자는 그것을 보존할지 선택할 수 있었다. 근사 크기는 저장 공간을 미리 할당하거나 공간이 충분해 보이는지 판단하는 데 도움이 될 수 있었지만, 정확한 다이제스트도, 완료된 쓰기의 접수 증명도, 할당이 성공한다는 보장도 아니었다.
개정판은 또한 확장 등록을 IANA를 통해 공식화했다. 현재의Content Disposition 레지스트리에는 원래 값들과 이후 프로토콜별 값들이 담겨 있다. 등록은 토큰에 공개적인 정의와 변경 절차를 부여한다. 그러나 그것이 특정 클라이언트가 이를 구현했음을, 또는 공유 레지스트리 옆에 나열된 모든 프로토콜에서 그 값이 타당함을 보여주지는 않는다.
사람 이름은 첫 봉투에 맞지 않았다
RFC 1806은 자신의 매개변수 문법이 파일 이름을 US-ASCII로 제한함을 인정했다. 이는 미관 이상의 문제였다. 제안된 로컬 이름은 사람을 위한 것인데도, 많은 사람이 자신의 문자 체계로는 평범한 파일 이름조차 쓸 수 없었다.
RFC 2231은 MIME 매개변수의 긴 값, 문자 집합, 언어 정보를 다루었다. 번호가 매겨진 세그먼트를 통해 긴 값을 순서대로 이어 쓸 수 있었다. 매개변수 이름 끝의 별표는 확장 값을 표시했는데, 접두사가 문자 집합과 선택적 언어를 이름 지정하고 그 뒤에 퍼센트 인코딩된 옥텟이 따랐다.
이것은 충실도를 높였지만 보존해야 할 추가 상태를 낳았다. 원시 세그먼트는 재배열되거나 빠질 수 있다. 인코딩된 세그먼트와 그렇지 않은 세그먼트가 섞일 수 있다. 문자 집합은 알 수 없거나 유효하지 않을 수 있다. 언어 태그는 바이트의 신원을 바꾸지 않으면서 표시를 도울 수 있다. 최종 유니코드 문자열은 원시 필드가 아니라 디코딩의 결과물이다.
사람 이름을 더 정확히 전송하는 것이 그 이름을 권위적으로 만들지는 않는다. 완벽하게 디코딩된 경로 탐색은 여전히 경로 탐색이다. 정확히 재구성된 예약 장치 이름도 여전히 위험하다. 인코딩은 표현을 해결할 뿐 허가를 내주지 않는다.
웹은 그 필드를 표준화하기 전에 먼저 빌려 썼다
1999년 무렵RFC 2616은 Content-Disposition이 HTTP 표준의 일부가 아니었음에도 RFC 1806에서 파생된 이 필드가 HTTP에서 흔히 구현되어 있다고 적을 수 있었다. 웹은 메일과 같은 필요를 발견했던 것이다. 원본 서버는 어떤 표현을 별도로 저장해야 한다고 말하고 유용한 이름을 제안하고 싶어 했다.
RFC 6266이 2011년 그 응답 헤더 용법을 표준화했다.attachment는 사용자 에이전트에 표현을 정상적으로 처리하는 대신 로컬 저장을 물어보도록 요청한다.inline은 평범한 처리를 기술하며, 이후 저장 작업을 위한 이름을 여전히 담을 수 있다.
HTTP 프로파일은 수신자의 의무를 더 날카롭게 했다. 파일 이름은 "참고용일 뿐(advisory only)"이었다. 사용자 에이전트는 서버가 무단 위치를 지정하는 것을 막아야 했고, 마지막 경로 세그먼트 외의 것을 모두 떼어내야 했으며, 위험한 후속 처리를 일으킬 수 있는 확장자를 신뢰해서는 안 되었고, 혼란을 주는 제어 문자나 공백을 제거해야 했고, 파일시스템이나 셸에서 특별한 의미를 지닌 이름을 무력화해야 했다.
레거시 범위를 넘는 이름을 위해 서버는 일반filename폴백과filename*확장 값을 함께 보낼 수 있고, 둘 다 지원하는 수신자는 후자를 선호해야 한다. 이후RFC 8187이 HTTP의 문자 집합·언어 매개변수 인코딩을 다듬고 UTF-8 지원을 요구했다. 우선순위 결정에는 자체 기록이 필요하다. 원시 값, 선택된 매개변수, 디코더, 결과적으로 표시된 이름이 각각 남아야 한다.
업로드는 같은 헤더를 반대 방향으로 사용했다
Content-Disposition은 멀티파트 폼 본문 안에도 있지만, 그것은 별개의 계약이다.RFC 6266은 multipart/form-data 같은 본문 부분 필드를 자신의 HTTP 응답 헤더 프로파일에서 명시적으로 제외한다.
RFC 7578은 각 form-data 부분이Content-Disposition: form-data와name매개변수를 실어야 한다고 요구한다. 파일 부분은 의미 있는 이름이 존재할 때filename을 포함해야 한다. 이 경로에서는 브라우저나 업로드 클라이언트가 발신자이고, 웹 응용 프로그램이 자신의 파일시스템을 지키는 쪽이 된다.
RFC 7578은 옛 규칙을 반복한다. 공급된 이름을 무비판적으로 쓰지 말고, 로컬 관례에 맞게 조정하고, 디렉터리 정보는 버리라는 것. 또한 이 본문 부분 맥락에서는 HTTP 응답이 사용하는filename*관례를 금지한다. 공유된 필드 이름이 맥락을 지우지는 않는다. 올바른 문법을 잘못된 프로토콜 위치에 적용하는 파서는 그럴듯하면서도 여전히 틀린 결과를 낼 수 있다.
따라서 이 역사는 단순히 "이메일 첨부가 브라우저 다운로드가 되었다"는 것이 아니다. 좁은 권한 계약의 이동이다. 메일, HTTP 응답, 폼 업로드를 통틀어 원격 쪽은 희망하는 처리를 기술하고 사람이 읽을 이름을 제안할 수 있다. 그러나 최종 행동은 여전히 로컬 쪽이 소유한다.
출처
회원 브리핑
프로필 심층 컨텍스트
올바른 멤버십 등급으로 로그인하면 전체 브리핑과 출처 노트를 볼 수 있습니다.
Strategic Circle 전용
Strategic Circle
모든 독자에게 공개됩니다. 가입 후 로그인하면 프로필 브리핑를 열람할 수 있습니다.
Strategic Circle 가입하기Leadership Alliance 전용
Leadership Alliance
자격을 갖춘 IP 자산 소유자 및 운영진을 위한 콘텐츠입니다. 로그인하면 Leadership Alliance 브리핑을 열람할 수 있습니다.
Leadership Alliance 가입하기





