본문 바로가기

이 포트폴리오의 원본은 https://cv.iruyo.com (심재빈) 입니다 · 출처 식별자 jbx-7f3a2e9b

← 기술 블로그

iOS·바이너리

캡처를 막는데 WebView만 화면이 깨진다 — 보호 속성을 View tree로 확장한 설계와 그 한계

iOS가 보안 입력 필드를 시스템 캡처에서 빼는 특성을 일반 View 계층으로 확장해 화면 전체를 캡처에서 제외한 설계, 동적 계층(WebView)에서 깨지는 한계, 그리고 iPhone Mirroring이라는 신종 경로를 정리한다.

금융·인증 앱 화면이 스크린샷·녹화·미러링으로 새어 나가는 것을 막아야 했다. 그런데 iOS에는 Android의 FLAG_SECURE 같은 한 줄짜리 캡처 차단이 없다. 앱 차원에서 화면 캡처를 막는 공식 API를 iOS는 거의 주지 않는다.

그래서 발상을 뒤집었다. 새로 만들지 말고, OS가 이미 내부적으로 갖고 있는 차단 동작을 찾아 빌려 쓰자.

단서는 보안 입력 필드에 있었다

비밀번호를 받는 보안 입력 필드를 떠올려 보자. 화면 녹화·미러링·스크린샷을 찍으면 그 필드 영역만 비거나 검게 칠해진다. OS가 민감 입력을 시스템 캡처 경로에서 의도적으로 빼기 때문이다.

여기서 중요한 사실 하나가 나온다. 차단 메커니즘은 이미 OS 안에 있고, 그 적용 범위가 보호 입력 필드 한 종류로 좁혀져 있을 뿐이다.

그렇다면 질문은 이렇게 바뀐다. 이 보호 속성을 입력 필드가 아닌 일반 View 타입까지 확장 적용할 수 있다면, 캡처에서 빠지는 영역을 화면 전체로 넓힐 수 있지 않을까.

보호 속성을 View tree로 확장한다

핵심 설계는 단순하다. 보호하려는 View를 보호 속성을 가진 컨테이너의 하위 계층으로 편입시킨다. 그러면 그 보호가 자식 View 트리 전체에 상속된다.

보이는 화면은 그대로 둔다. 시스템 캡처 경로에서만 빠지도록 계층 구조를 비트는 셈이다.

계층 구조 보호 속성 컨테이너 OS 캡처 제외 속성 보유 잔액·계좌 View 인증 코드 View ↳ 보호 속성 상속 사용자 화면 정상 렌더 그대로 보임 시스템 캡처 스크린샷·녹화 미러링에서 영역이 빠짐

이 메커니즘으로 특허를 공동 출원했다(‘텍스트 필드 보호 속성을 이용한 스크린 캡처 및 미러링 방지 장치 및 방법’). 공개 출원이라 원리 수준까지는 적어 둔다.

왜 이 방식이 더 견고한가

이 접근의 장점은 OS가 보장하는 차단을 그대로 쓴다는 데 있다. 화면을 별도 레이어로 가리거나, 캡처 이벤트를 감지해 사후에 검은 화면을 덮는 식이 아니다.

후자는 결국 타이밍 싸움이 된다. 한 프레임이라도 새면 무너진다. 반면 보호 속성 확장은 렌더 파이프라인 단계에서 OS가 영역을 빼 주므로, 새는 프레임 자체가 없다.

다만 어떤 계층 구조에 보호를 걸지와 한계 판정은 직접 했다.

WebView에서 화면이 깨지는 이유

문제는 모든 View가 정적인 계층을 갖지 않는다는 데서 터졌다. WebView나 동적 Container View는 내부 계층을 런타임에 스스로 재구성한다.

여기서 충돌이 난다. 우리가 보호 컨테이너 밑으로 편입시켜 둔 계층이 렌더 도중 갈아끼워지면, 상속시켜 둔 보호 속성이 끊기거나 합성 단계가 어긋난다. 그 결과 화면이 깨진다.

이건 단순한 실패가 아니다. 캡처는 막혔는데 사용자 눈에 보이는 화면까지 망가지는 것이라, 보호의 의미가 없다.

정적 계층 — 유지 보호 트리에 편입 계층 고정 → 속성 상속 지속 캡처 차단 + 화면 정상 의도대로 동작

동적 계층(WebView) — 깨짐 런타임에 내부 계층 재구성 편입한 노드가 갈아끼워짐 상속 끊김 → 화면 깨짐 캡처는 막혀도 화면이 망가짐

정직하게 막히는 지점을 긋는다

여러 우회를 시도했다. 동적 계층을 매 재구성마다 다시 보호 트리에 편입시키는 방식도 그중 하나였다. 하지만 비용과 깨짐 위험이 둘 다 컸다.

그래서 결정했다. WebView·동적 Container는 적용 대상에서 빼고, 이 한계를 고객 안내에 숨기지 않고 명시했다.

“이 구조에는 적용되지만 저 구조에는 깨진다”를 미리 말하는 편이, 적용 후 화면 깨짐으로 신뢰를 잃는 것보다 낫다. 막히는 지점을 명확히 그어 두는 것도 설계의 일부다.

iPhone Mirroring이라는 신종 경로

여기에 더해 iOS 18의 iPhone Mirroring이라는 새 노출 경로가 생겼다. Mac으로 iPhone 화면을 그대로 띄우는 기능이다.

문제는 이 미러링이 활성화됐는지를 앱이 판별할 공식 API가 없다는 점이다. 보호 속성 확장은 캡처 경로에는 그대로 걸린다. 하지만 미러링 활성 여부를 알아야 추가 대응을 하는 시나리오에서는, 판별 수단부터 없는 셈이다.

그래서 공식 API 부재 환경에서 대체 경로 3개를 비교하고, Apple 개발자 포럼 근거를 붙여 권장안을 도출했다.

결론

캡처 차단은 OS의 기존 보호 동작을 빌려 확장하는 것이 가장 견고하다. 새로 레이어를 덮거나 이벤트를 감지하는 방식과 달리, 새는 프레임이 원천적으로 없기 때문이다.

다만 그 전제는 두 곳에서 깨진다. 동적 계층, 그리고 신종 미러링 경로다. 그래서 차단·판별·안내를 하나로 묶지 말고, 분리해 운영해야 한다.