8.5. 출력에서 문자 인코딩을 제어해라

일반적으로 보안적인 프로그램들은 그들의 모든 가정들에 클라이언트들을 동기화시킴을 보증해야 한다. 대개 웹 애플리케이션에 영향을 미치는 한가지 문제는 출력의 문자 인코딩 지정을 잊는다는 것이다. 이는 모든 데이타가 신뢰된 출처로부터 온다면 문제가 되지 않지만 데이타 중 일부가 신뢰되지 않은 출처로부터 온다면 보안적인 프로그램이 예상한 것과 다른 인코딩을 사용하는 신뢰되지 않은 출처로부터의 데이타가 실제 데이타내에 몰래 삽입될 수도 있다. 이는 cross-site malicious content 공격에 대해 보안 구멍을 만드는 것으로 더욱 자세한 정보는 4.9절 를 보라.

CERT's tech tip on malicious code mitigation 은 지정되지 않은 문자 인코딩 문제를 매우 잘 설명하는데 이는 다음과 같다:

많은 웹페이지들은 문자 인코딩 (HTTP 에서 "charset" 매개변수) 을 정의하지 않은 채 두고 있다. HTML 과 HTTP 초기 버전에서는 문자 인코딩이 정의되어 있지 않으면 이를 디폴트로 ISO-8859-1 로 간주했는데 사실 많은 브라우저들은 다른 디폴트를 가지며 따라서 ISO-8859-1 디폴트에 의존하는 것은 불가능했다. HTML 버전 4 는 이를 합법화하는데 문자 인코딩이 지정되지 않으면 어떠한 문자 인코딩도 사용될 수 있다.

웹 서버가 어떤 문자 인코딩이 사용중인지를 지정하지 않으면 어떤 문자들이 특별한 것인지 알릴 수 없다. 문자 인코딩이 지정되지 않은 웹 페이지들은 대부분의 문자셋이 동일한 문자들에 128 미만의 바이트 값들을 할당하기 때문에 대부분 작동한다. 그러나 128 이상의 값들중에서 어떤 값들이 특별한가? 어떤 16 비트 문자 인코딩 체계들은 "<" 와 같은 특별 문자들에 대해 추가적인 멀티 바이트 표현을 갖고 있으며 어떤 브라우저들은 이러한 대체 인코딩을 인식해서 이에 따라 행동한다. 이는 ``정확한" 거동이지만 악의있는 스크립트를 사용한 공격을 예방하기 더욱 어렵게 만든다. 서버는 어떤 바이트 시퀀스가 특별 문자들을 나타내는지 단순히 모르고 있다.

예를 들어 UTF-7 은 "<" 과 ">" 에 대해 대체 인코딩을 제공하며 몇몇 널리쓰이는 브라우저들은 이를 시작 및 끝 태그로 인식한다. 따라서 이는 그러한 브라우저에서는 버그가 아니며 문자 인코딩이 실제로 UTF-7 이라면 이는 정확한 거동이다. 문제는 브라우저와 서버가 인코딩이 일치하지 않은 상황에 놓일 수도 있다는 것이다.

고맙게 이 문제를 설명하는 것이 어려움에도 불구하고 HTML 에서 이를 해결하는 것은 간단한데 HTML 헤더에 CERT 로부터의 다음 예와 같이 charset 을 단순히 지정하는 것이다:

<HTML>
<HEAD>
<META http-equiv="Content-Type"
content="text/html; charset=ISO-8859-1">
<TITLE>HTML SAMPLE</TITLE>
</HEAD>
<BODY>
<P>This is a sample HTML page
</BODY>
</HTML>

기술적 관점에서 보았을 때 더욱 좋은 접근 방법은 HTTP 프로토콜 출력의 일부분으로 문자 인코딩을 설정하는 것이다. 물론 어떤 라이브러리들은 이를 더욱 어렵게 만들기도 한다. 이는 클라이언트에게 헤더의 메타정보를 읽을 수 있게 하는 문자 인코딩을 결정하기 위해 헤더를 조사하도록 하지 못하기 때문에 기술적으로 더욱 좋다. 물론 실제로 메타 정보를 읽을 수 없고 이를 정확히 사용할 수 없는 브라우저가 판매 시장에서 성공할 수 없지만 이는 다른 문제이다. 어떤 경우든 이는 서버가 HTTP 프로토콜의 한 부분으로 원하는 값을 갖는 "charset" 을 보낼 필요가 있음을 의미한다. 불행히 어떤 예전 HTTP/1.0 클라이언트들은 명시적인 charset 매개변수를 적절히 다루지 못하기 때문에 이러한 기술적으로 더욱 좋은 접근 방법을 진지하게 추천하는 것은 어렵다. HTTP/1.1 스펙이 클라이언트에게 매개변수를 따르라고 요구함에도 불구하고 이를 유일한 메카니즘이 아닌 정확한 문자 인코딩 사용을 강요하는 부속물로 어떻게든 이를 사용해야 할만큼 충분한지는 의심스럽다.