Bezpieczny SVG

W jednej aplikacji nad którą pracuje odkryliśmy podatność dotyczącą plików SVG dostarczanych przez użytkowników. Szczegółowe wyjaśnienie jak można wykorzystać Scalable Vector Graphics do zrobienia Stored XSS dobrze opisał Sekurak.

Vizzdoom (autor posta na Sekuraku) sugeruje zwracanie odpowiednich nagłówków (Content-Type, X-Content-Type-Options i Content-Security-Policy) – co zawsze jest dobrym pomysłem! a także zachęca do użycia narzędzia SVGPurifier.

Wspomniana we wstępie aplikacja jest napisana w Javie (JDK11). Niestety, nie udało mi się znaleźć żadnej biblioteki, która odpowiadałaby możliwościami SVGPurifier’a przedstawionego przez Vizzdom’a.

Postanowiłem więc samemu stworzyć taką bibliotekę aby każdy użytkownik JVMa mógł łatwo weryfikować pliki SVG pod kątem występowania niepoprawnych tagów.

Strategia

Format SVG jest bardzo konkretnie opisany i pozwala na budowanie obrazów przy pomocy stosunkowo niewielkiego zbioru elementów i atrybutów. Dokładny opis tagów i ich atrybutów interpretowanych przez przeglądarki możemy znaleźć dzięki Mozilla Developer Network.

Elementy – https://developer.mozilla.org/pl/docs/Web/SVG/Element
Atrybuty – https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute

Przyjąłem następujący algorytm weryfikacji:

  • sprawdzamy czy wszystkie elementy (tagi) wewnątrz pliku SVG są tagami interpretowanymi podczas renderowania grafiki
  • sprawdzamy czy wszystkie atrybuty elementów wewnątrz pliku SVG są atrybutami interpretowanymi podczas renderowania grafiki

W przypadku wykrycia nieprawidłowych (nieznanych) elementów lub atrybutów, plik uznajemy za niebezpieczny.

Powyższy algorytm zaimplementowałem i opublikowałem na githubie: https://github.com/bgalek/safe-svg

Przykłady

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
<polygon id="triangle" points="0,0 0,50 50,0" fill="#009900" stroke="#004400"/>
<script type="text/javascript">
alert('Hello, world!');
</script>
</svg>
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
<polygon onclick="javascript:alert(1)" id="triangle" points="0,0 0,50 50,0" fill="#009900" stroke="#004400"/>
</svg>

Jeśli Twoja aplikacja wpuści powyższe definicję SVG – jest duża szansa, że masz podatność.

Safe-svg wykryje przemycony tag script oraz atrybut „onclick” – ponieważ nie znajdują się one na liście dozwolonych w svg elementów i atrybutów)

Napiszcie w komentarzu, jeśli znacie inne narzędzia pozwalające zweryfikować bezpieczeństwo SVG.


Autor Bartosz Gałek

Tak jak Obelix nie potrzebował magicznego napoju do bycia silnym, tak Bartosz nie potrzebuje kawy do tego, aby tryskać energią na prawo i lewo i zarażać nią zespół, któremu przewodzi jako Team Leader w Allegro.
Prywatnie, ogromny fan gier planszowych, zwolennik i współtwórca otwartego oprogramowania oraz ruchu DevOps.

Dodaj komentarz