NGINX LDAP 참조 구현 보안 취약점 해결

2022년 4월 9일에, NGINX LDAP 참조 구현에서 보안 취약점이 공개되었습니다. 우리는 참조 구현만 영향을 받는 것으로 판명되었습니다. NGINX 오픈소스와 NGINX Plus는 자체적으로 영향을 받지 않으며, 참조 구현을 사용하지 않는 경우 수정 조치가 필요하지 않습니다.

NGINX LDAP 참조 구현은 NGINX를 프록시하는 애플리케이션의 사용자를 인증하기 위해 Lightweight Directory Access Protocol (LDAP)을 사용합니다.
이는 Python 데몬 (Daemon)과 관련 NGINX 구성으로 게시되며, NGINX Github에서 찾을 수 있습니다.

만약 다음 중 하나라도 해당된다면, LDAP 참조 구현의 배포는 취약점의 영향을 받습니다.
아래에서는 각 조건에 대해 자세히 설명하고 어떻게 완화할 수 있는지에 대해 논의합니다.

  • 명령 줄 매개변수를 사용하여 Python 데몬을 구성합니다.
  • 사용되지 않는 선택적 구성 매개변수가 있습니다.
  • LDAP 인증은 특정 그룹 멤버십에 의존합니다.

참고 : NGINX LDAP 참조 구현은 통합 작업 및 검증에 필요한 모든 구성 요소 및 작동 방식을 설명하는 참조 구현으로 출판됩니다.
이는 production-grade 솔루션이 아닙니다. 예를 들어, 샘플 로그인 페이지에서 사용되는 사용자 이름 및 비밀번호에 대한 암호화가 없으며, 보안 공지에서 이러한 사실을 강조합니다.

목차

1. LDAP란?
2. Python 데몬 구성 시 매개변수 사용
3. NGINX LDAP 선택적 매개변수 구성
4. NGINX LDAP 그룹 멤버십 구성

1. LDAP란?

LDAP란 “Lightweight Directory Access Protocol”의 약자로, 네트워크 프로토콜 중 하나입니다. 이 프로토콜은 디렉토리 서비스에서 정보를 조회하고 수정하는 데 사용되며, 디렉토리는 트리(tree) 구조로 이루어진 데이터베이스로 보통 사용자, 컴퓨터, 그리고 그외의 리소스와 같은 네트워크 객체에 대한 정보를 저장합니다.

LDAP는 TCP/IP 위에서 동작하며, 클라이언트-서버 모델을 따릅니다. 클라이언트는 LDAP 메시지를 생성하고 이를 LDAP 서버로 전송합니다. 서버는 이러한 요청을 처리하고 클라이언트에게 결과를 반환합니다.

LDAP는 주로 회사나 그룹 내에서 중앙 집중화된 사용자와 리소스 정보를 관리하고, 이러한 정보에 대한 접근을 제어하는 데 사용됩니다. 예를 들어, 회사 내의 모든 사용자 계정 정보와 권한을 LDAP 서버에 저장하면, 이를 통해 효율적으로 사용자 인증 및 권한 부여 작업을 수행할 수 있습니다.

한편, LDAP는 X.500 표준을 기반으로 하지만, 더 간단하고 경량화된 버전입니다. 그래서 네트워크 상의 오버헤드가 적으며, 다양한 플랫폼과 어플리케이션에서 널리 지원되고 있습니다.

2. Python 데몬 구성 시 매개변수 사용

NGINX LDAP 참조 구현은 샘플 로그인 페이지에서 사용되는 사용자 이름 및 비밀번호의 암호화가 없으며, 보안 공지가 이를 밝혔다는 것을 예로 들어 프로덕션급 LDAP 솔루션이 아니라는 점을 강조해야 합니다.

LDAP 참조 구현을 구성하는 기본 방법은 샘플 구성 및 문서에서 설명하는 대로 여러 개의 proxy_set_header 지시문을 사용하는 것입니다. 그러나 구성 매개 변수는 Python 데몬을 초기화하는 명령 줄에서도 설정할 수 있습니다.

명령 줄에 구성 매개 변수가 지정되면, 악성 공격자는 특별히 조작된 HTTP 요청 헤더를 전달하여 그 중 일부 또는 전체를 무시할 수 있습니다. 이를 방지하려면, NGINX LDAP 구성의 location = /auth-proxy 블록에 다음 구성을 추가하여 인증 중에 모든 불필요한 요청 헤더가 무시되도록 해야 합니다.

location = /auth-proxy {
    # ...
    proxy_pass_request_headers off;
    proxy_set_header Authorization $http_authorization; # If using Basic auth
    # ...
}

3. NGINX LDAP 선택적 매개변수 구성

조건 1과 마찬가지로, 구성에서 명시적으로 설정되지 않은 경우 공격자는 특수하게 조작된 HTTP 요청 헤더를 전달하여 검색 템플릿을 재정의 할 수 있습니다. 이를 방어하려면 NGINX LDAP 구성의 location = /auth-proxy 블록에 다음 구성을 추가합니다.

location = /auth-proxy {
    # ...
    proxy_pass_request_headers off;
    proxy_set_header Authorization $http_authorization; # If using Basic auth
    # ...
}

4. NGINX LDAP 그룹 멤버십 구성

Python 데몬은 입력값을 검증하지 않습니다. 따라서 공격자는 특수하게 조작된 요청 헤더를 사용하여 그룹 멤버십 (memberOf) 확인을 우회하고, 인증되는 사용자가 필요한 그룹에 속하지 않더라도 인증을 성공시킬 수 있습니다.

이를 방지하기 위해, 로그인 양식을 제공하는 백엔드 데몬에서는 사용자 이름 필드에서 특수 문자를 제거해야 합니다.
특히 괄호 문자 (())와 등호 (=)는 LDAP 서버에서 특별한 의미를 가지기 때문에 제거해야 합니다. LDAP 참조 구현에서의 백엔드 데몬도 곧 이와 같이 업데이트될 예정입니다.