설명
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로 이전해야 합니다.
잠재적 영향
- 신뢰된 인증 기관이 발급했더라도 다른 호스트용인 인증서를 이용한 중간자 공격
- 서버 응답과 요청 데이터의 열람 또는 변조
- 세션 쿠키, 인증 토큰, 개인정보 등 전송 중인 민감 정보 탈취
해결 방법
default()와.none정책에서는validatesDomainName을true로 유지해 시스템 신뢰 체인과 요청 호스트를 함께 검증합니다.- 자체 서명 서버를 연결하기 위해 no-pinning 정책에
allowInvalidCertificates = true를 설정하고 호스트 이름 검증까지 끄지 않습니다. 공개적으로 신뢰되는 인증서를 사용하거나, 연결 전에 정확한 피어에 대한 인증서 또는 공개 키를 안전하게 배포합니다. - 위협 모델상 고정이 필요한 경우에만
.certificate또는.publicKey를 사용합니다. 고정을 적용할 호스트를 제한하고, 키 교체·백업 고정·실패 시 연결 차단 절차를 함께 설계합니다. 표준 시스템 신뢰와 호스트 이름 검증이 요구사항을 충족한다면 고정은 필수 조건이 아닙니다. - AFNetworking에서
URLSession의 기본 서버 신뢰 처리 또는 유지보수되는 Alamofire로 이전합니다. 2026-08-30에 확인한 Alamofire 안정 릴리스는 5.12.0입니다. 사용자 지정DefaultTrustEvaluator를 쓸 때에는 피어별 고정이 서비스 신원을 명시적으로 대신하는 경우가 아니라면validateHost: true를 유지합니다. - 릴리스 구성에서 호스트 이름 불일치, 만료, 신뢰되지 않은 발급자 인증서가 모두 거부되는지 테스트합니다.
예시
변경 전
import AFNetworking
func insecurePolicy() -> AFNetworking.AFSecurityPolicy {
let policy = AFNetworking.AFSecurityPolicy.default()
policy.validatesDomainName = false
return policy
}
변경 후
import AFNetworking
func standardPolicy() -> AFNetworking.AFSecurityPolicy {
let policy = AFNetworking.AFSecurityPolicy.default()
policy.validatesDomainName = true
return policy
}
설명:
- 변경 전: 신뢰 체인은 확인하지만 인증서의 호스트 이름을 요청 대상과 대조하지 않습니다.
- 변경 후: 시스템 신뢰 체인과 호스트 이름 검증을 모두 유지합니다.
validatesDomainName의 기본값도true이므로 이 대입은 보안 요구사항을 명확히 표시하는 용도입니다.
플랫폼 기본 서버 신뢰 처리로 이전할 때에는 불필요한 인증 챌린지 재정의를 추가하지 않습니다.
import Foundation
func standardSession() -> URLSession {
URLSession(configuration: .default)
}
참조
- AFNetworking 4.0.1 - AFSecurityPolicy.h
- AFNetworking 4.0.1 - AFSecurityPolicy.m
- AFNetworking 사용 중단 공지
- Apple - Preventing Insecure Network Connections
- Apple - Performing Manual Server Trust Authentication
- Alamofire - DefaultTrustEvaluator
- RFC 9525 - Service Identity in TLS
- CWE-297: Improper Validation of Certificate with Host Mismatch
- OWASP Top 10:2025 A04 - Cryptographic Failures