Swift AFNetworking 고정 미사용 정책의 호스트 이름 검증 비활성화

Swift AFNetworking 고정 미사용 정책의 호스트 이름 검증 비활성화

설명

AFNetworking 4.0.1의 AFSecurityPolicy.default()와 pinning mode .none은 인증서 또는 공개 키 고정을 사용하지 않지만, 기본적으로 시스템 신뢰 체인과 요청한 호스트 이름을 모두 검증합니다. 따라서 인증서 고정을 사용하지 않는다는 사실만으로 취약한 구성은 아닙니다.

이 정책에서 validatesDomainName을 false로 설정하면 AFNetworking은 요청 도메인에 결합된 SSL 정책 대신 기본 X.509 정책으로 서버 인증서를 평가합니다. 고정된 인증서나 공개 키도 없으므로, 신뢰 체인은 유효하지만 다른 호스트에 발급된 인증서가 수락될 수 있습니다. 네트워크 경로를 제어하는 공격자는 이를 이용해 대상 서버를 가장할 수 있습니다.

도메인이 있고 호스트 이름 검증이 켜진 no-pinning 정책에서 allowInvalidCertificates = true를 설정한 조합은 AFNetworking 4.0.1에서 거부됩니다. 이를 우회하려고 호스트 이름 검증까지 끄면 임의의 인증서를 허용할 수 있습니다. 사전에 올바르게 배포한 피어별 인증서 또는 공개 키 고정은 서비스 신원을 제공할 수 있습니다.

AFNetworking은 2023-01-17에 사용 중단되었고 더 이상 새 릴리스를 제공하지 않습니다. 유지보수되는 네트워크 라이브러리나 플랫폼 API로 이전해야 합니다.

잠재적 영향

  • 신뢰된 인증 기관이 발급했더라도 다른 호스트용인 인증서를 이용한 중간자 공격
  • 서버 응답과 요청 데이터의 열람 또는 변조
  • 세션 쿠키, 인증 토큰, 개인정보 등 전송 중인 민감 정보 탈취

해결 방법

  1. default()와 .none 정책에서는 validatesDomainName을 true로 유지해 시스템 신뢰 체인과 요청 호스트를 함께 검증합니다.
  2. 자체 서명 서버를 연결하기 위해 no-pinning 정책에 allowInvalidCertificates = true를 설정하고 호스트 이름 검증까지 끄지 않습니다. 공개적으로 신뢰되는 인증서를 사용하거나, 연결 전에 정확한 피어에 대한 인증서 또는 공개 키를 안전하게 배포합니다.
  3. 위협 모델상 고정이 필요한 경우에만 .certificate 또는 .publicKey를 사용합니다. 고정을 적용할 호스트를 제한하고, 키 교체·백업 고정·실패 시 연결 차단 절차를 함께 설계합니다. 표준 시스템 신뢰와 호스트 이름 검증이 요구사항을 충족한다면 고정은 필수 조건이 아닙니다.
  4. AFNetworking에서 URLSession의 기본 서버 신뢰 처리 또는 유지보수되는 Alamofire로 이전합니다. 2026-08-30에 확인한 Alamofire 안정 릴리스는 5.12.0입니다. 사용자 지정 DefaultTrustEvaluator를 쓸 때에는 피어별 고정이 서비스 신원을 명시적으로 대신하는 경우가 아니라면 validateHost: true를 유지합니다.
  5. 릴리스 구성에서 호스트 이름 불일치, 만료, 신뢰되지 않은 발급자 인증서가 모두 거부되는지 테스트합니다.

예시

변경 전

swift
import AFNetworking

func insecurePolicy() -> AFNetworking.AFSecurityPolicy {
    let policy = AFNetworking.AFSecurityPolicy.default()
    policy.validatesDomainName = false
    return policy
}

변경 후

swift
import AFNetworking

func standardPolicy() -> AFNetworking.AFSecurityPolicy {
    let policy = AFNetworking.AFSecurityPolicy.default()
    policy.validatesDomainName = true
    return policy
}

설명:

  • 변경 전: 신뢰 체인은 확인하지만 인증서의 호스트 이름을 요청 대상과 대조하지 않습니다.
  • 변경 후: 시스템 신뢰 체인과 호스트 이름 검증을 모두 유지합니다. validatesDomainName의 기본값도 true이므로 이 대입은 보안 요구사항을 명확히 표시하는 용도입니다.

플랫폼 기본 서버 신뢰 처리로 이전할 때에는 불필요한 인증 챌린지 재정의를 추가하지 않습니다.

swift
import Foundation

func standardSession() -> URLSession {
    URLSession(configuration: .default)
}

참조