신뢰할 수 없는 출처의 웹 기능 포함

Inclusion of Web Functionality from Untrusted Source

설명

외부 CDN 등 신뢰할 수 없는 도메인에서 스크립트·스타일·모듈을 로드할 때 발생합니다. 로드된 코드가 브라우저에서 동일 출처 권한으로 실행되므로, 공급망이 오염되면 악성 스크립트가 사용자 브라우저에서 그대로 동작합니다. 공격자는 도메인 소유권 변경, 서버 침해, DNS 변조 등을 통해 악성 코드를 배포할 수 있으며, 로드된 스크립트로 쿠키·토큰 탈취, DOM 변조, 키로깅, 피싱 유도 등을 수행할 수 있습니다. 2024년에 polyfill.io 도메인에서 실제로 악성 스크립트가 배포된 사례가 보고되었습니다.

잠재적 영향

  • 악성 스크립트 실행: 외부에서 내려온 코드가 1st-party 컨텍스트에서 실행되어 브라우저 내 모든 권한을 악용할 수 있음.

  • 세션/토큰 탈취: document.cookie, localStorage, OAuth 토큰 등을 탈취하여 계정 장악 가능.

  • 데이터 유출: 입력 폼, 결제 정보, 개인식별정보(PII) 등 민감 데이터가 외부로 전송될 수 있음.

  • 콘텐츠 변조/피싱 유도: DOM 조작을 통해 가짜 로그인 창, 결제창을 띄워 사용자를 속일 수 있음.

  • 공급망 오염 확산: 한 번의 오염으로 해당 스크립트를 쓰는 모든 페이지·사용자에게 피해가 전파됨.

해결 방법

  • polyfill.io 등 신뢰할 수 없는 도메인에서 스크립트/리소스를 로드하지 않습니다.

  • 가능하면 자체 호스팅(self-host)으로 필요한 polyfill/라이브러리를 고정 버전으로 배포합니다.

  • 외부 CDN이 불가피하다면 신뢰 가능한 CDN으로 교체하고, 정확한 버전 핀(pin)과 SRI(Subresource Integrity, integrity + crossorigin) 값을 사용합니다.

  • 동적 로딩(import(), createElement, fetch + eval 등)을 사용하는 경우, 허용 도메인(allowlist)을 코드/빌드 설정에 고정하고 런타임 변경을 막습니다.

  • CSP(Content-Security-Policy)로 script-src를 'self' 및 엄격한 allowlist로 제한하고, 가능하면 'strict-dynamic', 'nonce' 또는 'sha256-...' 해시를 사용합니다.

  • 레거시 브라우저 지원이 정말 필요한지 재검토하고, 폴리필은 기능 감지(Feature Detection) 기반으로 최소한만 로드합니다.

  • 제3자 리소스 변경 감시(무결성 검사, 모니터링)와 정기적 보안 리뷰를 수행합니다.

취약한 코드 및 안전한 코드 예시

취약한 코드

안전한 코드

설명:

  • 취약한 코드: 외부 polyfill.io 도메인에서 스크립트를 직접 로드합니다. 해당 도메인이 소유권 변경·침해·DNS 변조 등으로 오염되면 악성 JS가 동일 출처 권한으로 실행되어 쿠키/토큰 탈취, DOM 변조, 피싱 유도 등이 가능합니다. 또한 URL을 환경변수로 바꿀 수 있게 해 런타임에 임의 도메인으로 교체될 위험도 있습니다.

  • 안전한 코드: 검증된 파일을 자체 호스팅하고 고정 경로로 제공하여 제3자 도메인 의존을 제거했습니다. CSP로 script-src를 'self'로 제한해 외부 스크립트 로드를 차단합니다. 외부 CDN을 써야 한다면 버전 핀과 SRI를 적용해 파일 무결성을 보장하고, 허용 도메인만 명시해 동적 변경을 막아 공급망 공격 가능성을 크게 줄입니다.

참조

Last updated