요약

  • XMPP는 TLS와 SASL 협상의 성공을, 기존 XML 스트림을 통상적인 종료 태그나 TCP 연결 종료 없이 대체하는 경계로 다루었습니다.
  • 새로운 스트림 헤더, 스트림 ID, 기능 광고가 새로운 상태를 기술했습니다. TCP 연속성, 암호화, 상대 인증, SASL 성공, 리소스 바인딩, 스탠자 전송 허가는 서로 별개의 사실로 유지되었습니다.

파괴적 결과를 낳는 success 요소

XMPP 클라이언트가 서버에 XML 스트림을 열었다고 가정해 봅시다. 서버가 STARTTLS를 광고하고, 클라이언트가 진행을 요청하며, TLS 핸드셰이크가 성공합니다. 통상적인 직관은 이제 채널이 같은 채널인데 단지 암호화되었을 뿐이라고 말합니다. XMPP의 대답은 더 엄격합니다. TCP 연결은 같지만, XML 스트림은 그렇지 않습니다.

개시하는 주체는 암호화된 연결 위에서 새로운 스트림 헤더를 보냅니다. 보통 XML 스트림을 끝내는 종료 태그를 먼저 보내지는 않습니다. 수신 측은 새 스트림 ID를 생성하고, 새 헤더로 회신하며, 보호된 상태에 맞는 기능을 광고합니다. 기존 스트림은 대체된 것입니다.

인증도 같은 패턴을 반복합니다. 서버가 SASL<success/>를 내보내면, 그 성공은 교환이 이루어진 스트림의 유효성을 종료시킵니다. 클라이언트는 기존 TCP 연결 위에서 또 다른 스트림을 열고, 그 후에야 서버는 인증 이후 가능한 작업을 광고합니다. 적용되는 경우 리소스 바인딩도 여기에 포함됩니다.

이는 특이한 종류의 연속성입니다. 전송 계층은 정확히 애플리케이션 프로토콜이 이전 컨텍스트가 존속해서는 안 된다고 선언하는 동안 살아 있습니다.

연결과 스트림은 서로 다른 시계였다

RFC 6120은 XMPP를 근실시간 교환을 위한 XML의 애플리케이션 프로파일로 기술합니다. 그 스트림들은 애플리케이션 계층의 대상입니다. 엄밀히 말해 각 스트림은 단방향이며, TCP 자체가 양방향 트래픽을 전달하더라도 두 주체는 통상 각 방향마다 스트림 하나씩을 유지합니다.

이 구분은 재시작 시점에 중요합니다. 일반 규칙에 따르면 양측은 이전 스트림이 대체된 것으로 간주하고, 정상적인 종료</stream>태그를 보내지 않으며, 하위 TCP 연결도 끊지 않습니다. 양측은 연결을 재사용하며, 이 연결은 TLS가 활성화되어 상태가 달라졌을 수 있습니다. 개시 측은 새 여는 헤더를 제공하고, 수신 측은 새 스트림 ID를 제공합니다.

이를 '재접속'이라고 부르면 메커니즘을 놓칩니다. TCP 재접속은 새로운 전송 연관을 만들고 주소, 경로, 혼잡, 장애 조건을 다시 마주하게 됩니다. XMPP 재시작은 전송 계층은 유지하면서 XML 협상 컨텍스트를 비웁니다. 스트림 재개, 스탠자 재전송, 애플리케이션 전달 상태 복구와도 다릅니다. 이들은 서로 다른 근거를 가진 별개의 메커니즘입니다.

따라서 프로토콜은 하나의 소켓 위에 최소 세 개의 시계를 갖고 있었습니다. TCP에는 연결 수명이 있었고, TLS와 SASL은 특정 시점에 보안 또는 신원 상태를 바꾸었으며, 각 XML 스트림 세대는 자신만의 헤더, 식별자, 기능 집합, 허용되는 작업을 가졌습니다. 녹색 '연결됨' 표시기는 이 세 가지를 정확히 요약할 수 없었습니다.

기능은 단계별 권한 표면이었다

XMPP 스트림 기능은 서버가 언젠가 할 수 있는 모든 것의 영구 카탈로그가 아니었습니다. 기능들은 특정 단계에서 사용 가능하거나 요구되는 상호작용을 기술했습니다. 필수(mandatory)로 표시된 기능이 있다면 협상이 미완료라는 뜻이며, 일반적인 XML 스탠자는 아직 허가되지 않습니다. 빈 기능 집합, 혹은 자발적 기능만 담은 집합은 협상이 완료로 간주될 수 있음을 나타냅니다.

순서에도 의미가 담겼습니다. RFC 6120은 계층을 TCP, 그다음 TLS, 그다음 SASL, 그다음 XMPP로 기술합니다. 서버가 제공할 의향이 있는 SASL 메커니즘은 TLS가 이미 성립했는지에 따라 달라질 수 있습니다. 리소스 바인딩은 클라이언트가 인증을 마친 후에만 제공됩니다. 전환 사이에 기능 목록을 그대로 복사하면 이러한 의존 관계가 지워집니다.

재시작은 새로운 광고를 강제했습니다. 새 헤더가 도착하면 수신 주체는 갱신된 기능 집합을 보내야 했습니다. 이는 기능 공개를 이전의 더 약한 컨텍스트에서 물려받은 약속이 아니라 현재 상태에 상대적인 것으로 만들었습니다.

또한 부재에도 한계가 생겼습니다. 한 세대에서 기능이 보이지 않는다고 그 구현이 모든 세대에서 해당 기능이 없다는 증거는 되지 않습니다. 아직 자격이 없을 수도, 더 이상 적용되지 않을 수도, 정책에 의해 보류 중일 수도 있습니다.RFC 7590은 또 다른 경고를 더합니다. 공격자는 광고된 STARTTLS 기능이나 그required표시를 제거할 수 있습니다. 통신 기록은 해당 경로에 나타난 것의 근거이지 상대편에 대한 전지적 목록이 아닙니다.

TLS는 기존 지식을 부적격하게 만들었다

TLS 전환은 이후 바이트를 암호화하는 것 이상을 했습니다. RFC 6120은 성공 시 양측이 TLS가 효력을 발생하기 전에 TCP 위에서 안전하지 않은 방식으로 학습한 정보를 폐기할 것을 요구합니다. 예시에는 주장된from주소, 기존 스트림 ID, 기존 기능 목록이 포함됩니다.

이 규칙이 재시작에 가장 깊은 목적을 부여합니다. 보호된 스트림이 보호되지 않은 스트림에서 모든 것을 물려받는다면, 능동적 중개자가 TLS 이전의 주장을 변경함으로써 이른바 보안 세션에 영향을 줄 수 있습니다. 새 헤더와 기능은 장식적인 반복이 아닙니다. 어떤 진술이 새 보안 컨텍스트에서 살아남는지를 확립합니다.

그럼에도 근거는 세분화되어 남습니다. TLS는 채널을 보호하면서 상대 인증은 실패하거나, 약하거나, 아예 없을 수 있습니다. RFC 7590은 XMPP의 TLS 실무를 강화하고, 클라이언트가 서버를, 서버가 클라이언트를 인증하도록 요구하며, 서버 간 인증을 강하게 권장합니다. 그러면서도 암호화되었으나 인증되지 않은 서버 간 연결을 별개의, 더 약한 사례로 논의합니다.

따라서 'TLS 성공'은 완전한 신원 진술이 아닙니다. 운영자는 버전과 매개변수, 인증서 또는 다른 검증 방법, 대상 신원, 검증 결과, 정책 결정을 파악해야 합니다. 새 스트림은 프로토콜이 경계를 넘었다는 사실을 말할 뿐, 경계가 실제로 무엇을 확립했는지 기록할 책임을 관찰자에게 면제해 주지 않습니다.

SASL 성공은 신원 상태를 바꾸었지 모든 권한을 바꾸지는 않았다

RFC 4422는 SASL을 연결 지향 프로토콜이 교체 가능한 인증 메커니즘을 사용할 수 있게 하는 프레임워크로 정의합니다. 이 프레임워크는 인증 신원, 인가 신원, 교환 결과, 메커니즘이 협상할 수 있는 데이터 보안 계층을 분리합니다. 모든 메커니즘이 동일한 속성을 제공하지는 않습니다.

XMPP는 이 프레임워크를 XML 안에서 프로파일링합니다. SASL 협상 이후 양측은 스트림을 재시작해야 합니다.<success/>를 받으면 클라이언트는 기존 TCP 연결 위에서 이전 종료 태그를 보내지 않은 채 새 스트림을 엽니다. 수신 측은 새 스트림 ID를 할당하고 이제 사용 가능한 기능을 광고합니다.

인증과 인가의 구분이 중요합니다. SASL은 누가 자격 증명을 제시했는지, 지원되는 경우 어떤 신원을 대행하여 행동하려 하는지를 확립할 수 있습니다. 하지만 모든 스탠자를 허용하거나, 클라이언트 리소스를 자동으로 바인딩하거나, 다른 엔드포인트가 애플리케이션 메시지를 수신할 것을 증명하지는 않습니다.

클라이언트-서버 스트림에서는 인증 이후에도 리소스 바인딩이 여전히 필수입니다. 서버는 바인딩 기능을 SASL 이후 스트림에서만 제시합니다. 바인딩이 완료되기 전에 클라이언트가 다른 주체에게 스탠자를 보내려 하면 단순히 '이르다'는 수준이 아니며, RFC 6120은 서버가 이를 처리하지 말고not-authorized오류로 스트림을 닫을 것을 요구합니다.

성공은 따라서 의도적으로 불완전했습니다. 하나의 협상을 끝내고, 사실을 바꾸고, 다음 의무를 드러냈습니다.

마지막 필수 단계는 다시 재시작하지 않았다

리소스 바인딩은 인증된 계정과 스트림에 리소스 식별자를 붙입니다. 이는 하나의 연결된 리소스를 다른 리소스와 구분합니다. 그러나 RFC 6120은 바인딩 이후에는 재시작해서는 안 된다고 명시합니다.

이 부정 규칙은 잘못된 일반화를 막습니다. XMPP는 무언가가 성공할 때마다 재시작하지 않았습니다. TLS와 SASL은 보안 또는 신원 컨텍스트가 이전 스트림 지식을 무효화하는 경계를 넘었습니다. 바인딩은 이미 인증된 스트림 안의 이후 단계를 완성한 것입니다. 그 결과는 주소 지정과 스탠자 허가를 바꾸었지만, 사양은 또다시 비우기를 요구하지 않았습니다.

따라서 엔드포인트에는 성공 불리언들의 모음이 아니라 상태 머신이 필요했습니다. TLS 이전에는 일부 광고된 정보가 잠정적이었습니다. TLS 이후에는 SASL이 여전히 필수였습니다. SASL 이후에는 클라이언트에게 바인딩이 필수였습니다. 바인딩 이후에 스탠자가 일반 애플리케이션 경로로 들어갈 수 있었습니다. 각 전환마다 담당자, 실패 표면, 결과가 달랐습니다.

이 순서는 로그가 주장할 수 있는 범위도 제한합니다. 새 스트림 ID는 사용자 ID가 아니고, 바인딩된 리소스는 전달 확인 증명이 아니며, 로컬 서버가 수용한 스탠자는 원격 애플리케이션 효과의 증거가 아닙니다. 프로토콜은 진행 상황을 관찰 가능하게 하면서도 진행을 결과와 합치지 않습니다.

2004년 설계는 명시적인 대체 모델이 되었다

2004년 10월에 발행된RFC 3920은 이미 TLS 성공 이후와 SASL<success/>이후에 새 스트림을 요구했습니다. 이 문서는 TCP, TLS, SASL, XMPP의 순서를 명시하고, 그 성공 시점에 원래 스트림이 종료 태그 없이 닫힌 것으로 다루었습니다.

RFC 6120은 2011년에 그 문서를 폐기(obsolete)했습니다. 그 정식화는 일반 아키텍처를 더 명확히 했습니다. 기존 연결을 재사용하고, 이전 스트림이 대체된 것으로 간주하며, 새 스트림 ID를 생성하고, 새 단계를 위한 기능을 다시 보낸다는 것입니다. 변화는 '재시작 없음'에서 '재시작'으로의 전환이 아니었습니다. 재시작이 존재하는 이유와 재구성해야 할 상태가 무엇인지에 대한 더 체계적인 서술이었습니다.

그다음 RFC 7590은 위협 모델이 진화함에 따라 2015년에 TLS 환경을 강화했습니다. 그러나 스트림 재시작을 안전한 배포의 증거로 만들지는 않았습니다. 대신 프로토콜 안무(choreography)를 인증서 검증, 다운그레이드 저항, 운영 정책과 구분해야 할 필요성을 강화했습니다.

남는 교훈은 소박하지만 강력합니다. 연속성은 하나의 것이 아닙니다. 전송 연결을 유지하면 효율을 보존할 수 있습니다. 애플리케이션 스트림을 대체하면 인식적 위생을 보존할 수 있습니다. 한 보호 체계 아래에서 학습한 사실이 다른 보호 체계의 권위를 은연중에 획득해서는 안 됩니다.

출처