“A vicious circle of incompatibility”

Marcin Wichary

비호환성의 악순환

원문은 Marcin Wichary님이 에 게재했습니다. 이 블로그 구독하기

PortalRunner의 재미있는 16분짜리 영상은 이런 전제로 시작합니다:

이건 고양이 사진이 담긴 이미지 파일입니다. 그런데 확장자를 .MP4로 바꾸면 역시 고양이가 나오는 비디오 파일이 됩니다. .PDF로 바꾸면 이 영상의 대본이 담긴 텍스트 문서가 되죠. 이름만 바꾸는 것만으로 유효한 웹페이지가 될 수도, .ZIP 압축 파일이 될 수도, 파워포인트 프레젠테이션이 될 수도 있습니다. 이런 파일을 가끔 “폴리글랏”이라고 부르기도 합니다(다만 보통 이 용어는 여러 프로그래밍 언어에서 모두 동작하는 코드를 가리킵니다).

이런 파일이 실제로 필요할 일은 거의 없겠지만, 파일 형식의 헤더와 구조에 대한 다양한 접근 방식을 재미있게 들여다볼 수 있는 사례입니다. 평소에는 잘 생각해 보지 않는 주제이기도 하고요.

영상 중간에는 흥미로운 곁다리 이야기도 숨어 있습니다. 파일 확장자는 그저 파일을 올바른 애플리케이션으로 전달하기 위한 수단에 불과한 걸까요? 예를 들어 .jpeg를 .gif로 이름을 바꿨는데 둘 다 Pixelmator로 연결된다면, Pixelmator는 내부적으로 JPEG 파일임을 최대한 감지해 처리해야 할까요, 아니면 “이건 GIF 파일 같지 않습니다”라는 메시지를 띄우며 실패해야 할까요?

웹에도 MIME 스니핑이라는 비슷한 문제가 있습니다. “MIME”은 웹에서의 확장자 같은 것이고, “스니핑”은 다른 것은 모두 무시하고 내용물만으로 파일의 종류를 판별한다는 뜻입니다. 여기에는 보안상의 고려 사항도 따랐는데, 악의적인 행위자가 무해해 보이는 것으로 위장해 악성 코드를 몰래 집어넣을 수 있었기 때문입니다. 영상이 재미로 하는 일을 무기화한 셈이죠.

이 블로그치고는 꽤 기술적인 이야기지만, MIME 스니핑에 대한 위키백과 항목 안에 눈에 띄는 구절이 있었습니다:

[MIME 스니핑은 일부 브라우저에서 여전히 사용됩니다. 하지만] 콘텐츠에 MIME 타입을 올바르게 지정하지 않은 사이트도 해당 브라우저에서는 정상적으로 작동하는 것처럼 보이게 함으로써, 올바른 라벨링을 장려하지 못하게 되고, 그 결과 해당 사이트들이 작동하려면 오히려 콘텐츠 스니핑이 필요해져, 웹 표준 및 보안 모범 사례와의 비호환성이라는 악순환을 만들게 됩니다.

MIME 스니핑이 등장하기 수십 년 전, 존 포스텔은 포스텔의 법칙이라는 말을 만들며 이러한 사고방식의 본질을 짚어냈습니다. “보낼 때는 보수적으로, 받을 때는 관대하게”라는 법칙이죠. 매력적인 원칙이지만, 위 인용문과 비슷한 문제를 안고 있습니다:

결함이 사실상 표준으로 굳어질 수 있습니다. 프로토콜의 모든 구현은 그 비정상적인 동작을 그대로 재현해야 하며, 그렇지 않으면 상호 운용성을 갖출 수 없습니다. […] 이런 환경에서 상호 운용성을 보장하는 것을 흔히 “버그까지 호환되는” 것을 목표로 한다고 표현합니다.

포스텔의 법칙은 컴퓨터 시스템 안팎으로 오가는 데이터에 관한 이야기였지만, 제게 이 전제는 훨씬 더 오래가는, 다른 많은 것에도 적용되는 디자인 질문으로 다가옵니다. “받는 것에 관대해지는” 것은 도움이 되는 것처럼 느껴질 수 있지만, 사용자에게 나쁜 습관을 가르치고 더 큰 결과를 초래할 수도 있습니다. 이런 원칙이 적용되는 모든 프로젝트에서는 이렇게 자문해 볼 가치가 있습니다. 사용자가 실수를 해도 굳이 나서서 도와줘야 할까, 아니면 더 엄격하게 굴어 규칙을 제대로 따르도록 가르치는 편이 장기적으로 사용자에게 이득이 될까?

이전에 링크했던 Command Line Interface Guidelines에 이와 관련한 훌륭한 예시가 있습니다:

제안한 명령어를 실행할지 물어볼 수는 있지만, 강제로 실행해서는 안 됩니다. 예를 들어:

$ heroku pss
› Warning: pss is not a heroku command.
Did you mean ps? [y/n]:

수정된 구문을 제안하는 대신, 처음부터 올바르게 입력한 것처럼 대신 실행해 주고 싶은 유혹을 느낄 수도 있습니다. 때로는 그게 옳은 일일 수도 있지만, 항상 그런 것은 아닙니다.

첫째, 잘못된 입력이 단순한 오타를 의미하는 것은 아닙니다. 사용자가 논리적인 실수를 했거나 셸 변수를 잘못 사용했을 수도 있습니다. 사용자가 의도한 바를 추측하는 것은 위험할 수 있으며, 특히 그에 따른 동작이 상태를 변경하는 경우에는 더욱 그렇습니다.

둘째, 사용자가 입력한 내용을 바꿔 버리면 올바른 구문을 배울 기회를 빼앗게 된다는 점을 명심하세요. 사실상 사용자가 입력한 방식이 유효하고 올바르다고 인정하는 셈이며, 그 방식을 무기한으로 지원하겠다고 약속하는 것이 됩니다. 그런 결정을 내릴 때는 의도를 명확히 하고, 두 가지 구문을 모두 문서화하세요.

이 글은 muse-spark-1.2-contributor 모델을 사용해 번역했습니다.

댓글