최신 웹 애플리케이션에서 사용자 데이터를 안전하게 호스팅

David Dworken
David Dworken

많은 웹 애플리케이션에서 사용자 제어 콘텐츠를 표시해야 합니다. 사용자가 업로드한 이미지 (예: 프로필 사진)를 제공하는 것만큼 간단할 수도 있고 사용자 제어 HTML (예: 웹 개발 튜토리얼)을 렌더링하는 것만큼 복잡할 수도 있습니다. 이를 안전하게 실행하는 것은 항상 어려웠으므로 Google은 대부분의 웹 애플리케이션 유형에 적용할 수 있는 간단하면서도 안전한 솔루션을 찾기 위해 노력해 왔습니다.

신뢰할 수 없는 콘텐츠를 격리하는 기존 솔루션

사용자 제어 콘텐츠를 안전하게 제공하는 기존 솔루션은 샌드박스 도메인이라고 하는 것을 사용하는 것입니다. 기본 개념은 애플리케이션의 기본 도메인이 example.com인 경우 exampleusercontent.com에서 신뢰할 수 없는 모든 콘텐츠를 제공할 수 있다는 것입니다. 이 두 도메인은 교차 사이트이므로 exampleusercontent.com의 악성 콘텐츠는 example.com에 영향을 미칠 수 없습니다. 이 접근 방식을 사용하면 이미지, 다운로드, HTML을 비롯한 모든 종류의 신뢰할 수 없는 콘텐츠를 안전하게 제공할 수 있습니다. 이미지나 다운로드에 이를 사용할 필요가 없는 것처럼 보일 수 있지만 이렇게 하면 특히 기존 브라우저에서 콘텐츠 스니핑으로 인한 위험을 방지하는 데 도움이 됩니다. 샌드박스 도메인은 업계 전반에서 널리 사용되며 오랫동안 잘 작동해 왔습니다. 하지만 다음과 같은 두 가지 주요 단점이 있습니다.

  • 애플리케이션은 종종 콘텐츠 액세스를 단일 사용자로 제한해야 하며, 이를 위해서는 인증 및 승인을 구현해야 합니다. 샌드박스 도메인은 기본 애플리케이션 도메인과 쿠키를 공유하지 않으므로 이를 안전하게 실행하기가 매우 어렵습니다. 인증을 지원하려면 사이트에서 기능 URL을 사용하거나 샌드박스 도메인에 별도의 인증 쿠키를 설정해야 합니다. 이 두 번째 방법은 많은 브라우저에서 기본적으로 교차 사이트 쿠키를 제한하는 최신 웹에서 특히 문제가 됩니다.
  • 사용자 콘텐츠는 기본 사이트와 격리되지만 다른 사용자 콘텐츠와는 격리되지 않습니다. 이로 인해 악성 사용자 콘텐츠가 샌드박스 도메인의 다른 데이터를 공격할 위험이 발생합니다 (예: 동일 출처 데이터 읽기).

또한 샌드박스 도메인은 리소스가 격리된 도메인으로 명확하게 분할되므로 피싱 위험을 완화하는 데 도움이 됩니다.

사용자 콘텐츠를 제공하는 최신 솔루션

시간이 지남에 따라 웹이 발전했으며 이제 신뢰할 수 없는 콘텐츠를 제공하는 더 쉽고 안전한 방법이 있습니다. 여기에는 다양한 접근 방식이 있으므로 Google에서 사용하는 두 가지 솔루션을 간략하게 설명하겠습니다.

접근 방식 1: 비활성 사용자 콘텐츠 제공

사이트에서 비활성 사용자 콘텐츠 (예: 이미지 및 다운로드와 같이 HTML 또는 JavaScript가 아닌 콘텐츠)만 제공해야 하는 경우 이제 격리된 샌드박스 도메인 없이 안전하게 실행할 수 있습니다. 두 가지 주요 단계가 있습니다.

  • 항상 Content-Type 헤더를 모든 브라우저에서 지원되고 활성 콘텐츠가 포함되지 않은 잘 알려진 MIME 유형으로 설정합니다. 확실하지 않은 경우 application/octet-stream을 선택하는 것이 안전합니다.
  • 또한 브라우저가 응답을 완전히 격리하도록 항상 응답 헤더를 설정합니다.
응답 헤더 목적

X-Content-Type-Options: nosniff

콘텐츠 스니핑을 방지합니다.

Content-Disposition: attachment; filename="download"

렌더링하는 대신 다운로드를 트리거합니다.

Content-Security-Policy: sandbox

별도의 도메인에서 제공되는 것처럼 콘텐츠를 샌드박스 처리합니다.

Content-Security-Policy: default-src ‘none'

JavaScript 실행 (및 하위 리소스 포함)을 사용 중지합니다.

Cross-Origin-Resource-Policy: same-site

페이지가 교차 사이트에 포함되지 않도록 방지합니다.

이 헤더 조합을 사용하면 응답을 애플리케이션에서 하위 리소스로만 로드하거나 사용자가 파일로 다운로드할 수 있습니다. 또한 헤더는 CSP 샌드박스 헤더와 default-src 제한을 통해 브라우저 버그로부터 여러 겹으로 보호해 줍니다. 전반적으로 설명된 설정은 이러한 방식으로 제공되는 응답이 삽입 또는 격리 취약점으로 이어질 수 없다는 높은 수준의 확신을 제공합니다.

심층 방어

제안된 솔루션은 일반적으로 XSS에 대한 충분한 방어를 제공하지만 추가 보안 계층을 제공하기 위해 적용할 수 있는 여러 가지 추가 강화 조치가 있습니다.

  • IE11과의 호환성을 위해 X-Content-Security-Policy: sandbox 헤더를 설정합니다.
  • 엔드포인트가 삽입되지 않도록 Content-Security-Policy: frame-ancestors 'none' 헤더를 설정합니다.
  • 다음과 같이 격리된 하위 도메인에서 사용자 콘텐츠를 샌드박스 처리합니다.
    • 격리된 하위 도메인에서 사용자 콘텐츠를 제공합니다 (예: Google은 product.usercontent.google.com과 같은 도메인을 사용함).
    • Cross-Origin-Opener-Policy: same-originCross-Origin-Embedder-Policy: require-corp를 설정하여 교차 출처 격리를 사용 설정합니다.

접근 방식 2: 활성 사용자 콘텐츠 제공

활성 콘텐츠 (예: HTML 또는 SVG 이미지)를 안전하게 제공하는 것도 기존 샌드박스 도메인 접근 방식의 약점 없이 실행할 수 있습니다.

가장 간단한 옵션은 Content-Security-Policy: sandbox 헤더를 활용하여 브라우저에 응답을 격리하도록 지시하는 것입니다. 모든 웹브라우저가 샌드박스 문서에 프로세스 격리를 구현하는 것은 아니지만 브라우저 프로세스 모델을 지속적으로 개선하면 샌드박스 처리된 콘텐츠와 삽입 애플리케이션의 분리가 개선될 수 있습니다. SpectreJS렌더러 손상 공격이 위협 모델 외부에 있는 경우 CSP 샌드박스를 사용하는 것이 충분한 솔루션일 수 있습니다. Google에서는 샌드박스 도메인 개념을 현대화하여 신뢰할 수 없는 활성 콘텐츠를 완전히 격리할 수 있는 솔루션을 개발했습니다. 핵심 아이디어는 다음과 같습니다.

기존 샌드박스 도메인 접근 방식과 비교할 때 이렇게 하면 모든 콘텐츠가 고유한 사이트에서 완전히 격리됩니다. 또한 기본 애플리케이션에서 렌더링할 데이터를 가져오도록 하면 더 이상 기능 URL을 사용할 필요가 없습니다.

결론

이 두 솔루션을 함께 사용하면 googleusercontent.com과 같은 기존 샌드박스 도메인에서 서드 파티 쿠키 차단과 호환되는 더 안전한 솔루션으로 마이그레이션할 수 있습니다. Google에서는 이미 많은 제품을 이러한 솔루션을 사용하도록 마이그레이션했으며 내년에 더 많은 마이그레이션을 계획하고 있습니다.