Przejdź do treści
INDEKS ANALIZ BREACHROAD / NOTA TECHNICZNA

SiYuan CVE-2026-73041–73054: stored XSS przechodzi w Electron RCE

Adnotacje PDF, kalkulacje i metadane baz trafiają do innerHTML, a Node Integration zwiększa skutek do wykonania kodu. Analizujemy falę CVE i v3.7.4.

MATERIAŁ PUBLICZNY
AUTOR
/ CEO Breachroad · OSCP · PNPT
PUBLIKACJA
15 sierpnia 2026
CZAS CZYTANIA
16 min czytania
TEMAT
Podatności i CVE
SiYuan CVE-2026-73041–73054: stored XSS przechodzi w Electron RCE

15 sierpnia 2026 roku w bazach CVE pojawiła się fala rekordów dotyczących SiYuan przed wersją 3.7.4. Wiele z nich ma ten sam wzorzec: dane dokumentu lub bazy są zapisywane bez restrykcyjnego modelu, później trafiają do HTML przez innerHTML albo insertAdjacentHTML, a skrypt wykonuje się w desktopowym rendererze Electron. Ponieważ okna aplikacji mają dostęp do Node.js, klasyczny stored XSS może przekroczyć granicę interfejsu i prowadzić do wykonywania kodu na komputerze użytkownika.

Wśród opublikowanych rekordów znalazły się CVE-2026-73041 dla adnotacji PDF, CVE-2026-73042 dla metadanych menu bazy, CVE-2026-73043 dla kalkulacji Template, CVE-2026-73044 dla szerokości kolumn oraz kolejne luki w polach i ikonach widoku atrybutów. Oceny CVSS 4.0 wielu z nich sięgają 9,4. Osobne rekordy opisują też brute force kodu dostępu i obejście uwierzytelnienia WebSocket.

Ten wpis rozwija temat SiYuan z poprzedniego dnia: SQL injection dotyczyło granicy danych w SQLite, natomiast seria z 15 sierpnia pokazuje problem granicy między treścią, DOM i systemem operacyjnym.

Wspólny mnożnik: konfiguracja Electron

W zwykłej aplikacji webowej XSS pozwala działać w kontekście originu: czytać widoczne dane, wykonywać żądania i przejmować sesję. Jest poważny, lecz sandbox przeglądarki nadal oddziela stronę od systemu plików i procesów hosta.

Desktopowy SiYuan korzysta z Electron. Advisory wskazują nodeIntegration: true, contextIsolation: false i webSecurity: false w oknach renderera. W takim modelu JavaScript uruchomiony w DOM może sięgnąć po moduły Node, a więc granica XSS–RCE staje się bardzo cienka. Sanitizer nie chroni tylko wyglądu strony; jest barierą przed dostępem do systemu operacyjnego.

To nie znaczy, że Electron jest z definicji niebezpieczny. Bezpieczny profil wyłącza Node Integration w rendererze, włącza contextIsolation, stosuje sandbox i udostępnia przez preload wyłącznie wąskie, sprawdzane operacje. Gdy renderer ma pełne capabilities, każdy pominięty escape w interfejsie dziedziczy maksymalny skutek.

CVE-2026-73041: adnotacja PDF jako nośnik kodu

Advisory CVE-2026-73041 opisuje endpoint setFileAnnotation, który zapisuje dostarczony przez klienta string do pliku sidecar .sya bez parsowania i walidacji schematu. Podczas renderowania PDF funkcja showHighlight interpoluje kilka pól adnotacji bezpośrednio do atrybutów HTML i dołącza wynik przez insertAdjacentHTML.

Ten szczegół jest ważny: adnotacja nie jest wyłącznie lokalnym stanem UI. Plik sidecar przechodzi z dokumentem przez eksport, import, synchronizację i zmianę nazwy. Współdzielony notatnik lub paczka z PDF może więc przenieść payload na inne urządzenie. Wykonanie następuje, gdy odbiorca otworzy dokument i renderer narysuje adnotacje.

Kod tuż obok używa setAttribute dla jednego pola, co jest bezpieczniejszym sposobem budowania elementu. Problem pokazuje, że częściowa poprawność nie wystarcza. Wszystkie pola kontrolowane przez dane muszą przejść przez bezpieczny interfejs DOM lub spójne kodowanie kontekstowe.

CVE-2026-73043: kalkulacja Template staje się HTML

Advisory CVE-2026-73043 dotyczy operatora kalkulacji Template w bazie. Serwer renderuje tekst/template Go i przechowuje wynik jako zwykły tekst. Klient umieszcza ten rezultat w znaczniku span, a następnie przypisuje zbudowany fragment przez innerHTML.

Nie jest potrzebna klasyczna template injection pozwalająca wywoływać niebezpieczne funkcje. Go text/template przepuszcza tekst literalny, więc sam wynik może zawierać markup. Projekt posiada już funkcję getAVTemplateHTML z DOMPurify dla blisko spokrewnionej ścieżki kolumny szablonowej, ale ścieżka kalkulacji jej nie wywoływała. Dwie funkcje prezentujące ten sam rodzaj danych miały różne polityki.

Payload może podróżować przez import, synchronizację, współdzielony workspace lub rozproszony pakiet. Zwykłe otwarcie widoku wyświetlającego stopkę kalkulacji wystarcza do uruchomienia renderowania. W kliencie desktopowym skutek wychodzi poza DOM dzięki Node Integration.

CVE-2026-73042 i 73044: metadane też są aktywną treścią

CVE-2026-73042 obejmuje nazwy i opisy pól używane w menu grup, widoków i edycji. Advisory metadanych menu pokazuje, że wartość mogła zostać poprawnie zakodowana w jednym atrybucie, a jednocześnie pozostawiona surowa w treści tej samej linii HTML. Użytkownik uruchamiał sink dopiero po otwarciu określonego menu.

CVE-2026-73044 dotyczy szerokości kolumn widoku atrybutów. Advisory szerokości kolumn opisuje brak walidacji wartości zapisywanej przez API i późniejsze wklejenie jej do atrybutu style. Złośliwa wartość mogła opuścić kontekst stylu i dodać handler zdarzenia do wielu komórek.

Kolejne rekordy z tej serii obejmują między innymi kolor opcji select, nazwy pól w sortowaniu i konwersję kodu Unicode ikony. Lista różni się miejscem w UI, ale przepływ pozostaje ten sam: zapis niezaufanej wartości → późniejsze odczytanie → interpolacja do HTML → wykonanie w uprzywilejowanym rendererze.

Dlaczego lista pojedynczych escape’ów nie wystarcza

Kodowanie zależy od kontekstu. Tekst elementu, atrybut HTML, URL, CSS i JavaScript wymagają innych reguł. Funkcja bezpieczna dla treści span nie musi być bezpieczna dla style. Ręczne dodawanie escape w kolejnych miejscach łatwo prowadzi do regresji i niespójności.

Preferowanym rozwiązaniem jest budowanie elementów przez textContent, setAttribute i typowane właściwości DOM. Jeśli aplikacja świadomie dopuszcza fragment HTML, powinna mieć jeden centralny sanitizer z jasno określonym profilem i testami. Dane zapisane jako tekst muszą pozostać tekstem aż do renderowania.

Druga warstwa to redukcja możliwości renderera. Nawet jeżeli jeden XSS przetrwa sanitizer, brak Node Integration i izolowany preload ograniczają skutek. Defense in depth jest konieczne, bo w dużym edytorze istnieją dziesiątki sinków i formatów treści.

Kto jest narażony

Advisory oznaczają jako dotknięte wydania sprzed v3.7.4. Najwyższe ryzyko dotyczy klienta desktopowego Electron, gdzie JavaScript może osiągnąć Node. W wersjach webowych te same luki mogą pozostać XSS-em z dostępem do danych i operacji aplikacji, nawet jeśli nie dają bezpośredniego RCE hosta.

Szczególnie narażone są zespoły synchronizujące wspólne workspace’y, importujące bazy lub pakiety i otwierające dokumenty od innych osób. Napastnik nie musi przesyłać klasycznego pliku wykonywalnego. Payload może znajdować się w polu wyglądającym jak metadana, szerokość, kolor lub adnotacja.

Warto uwzględnić stacje deweloperów. SiYuan uruchomiony na koncie mającym klucze SSH, tokeny Git, konfiguracje chmurowe i dostęp VPN zwiększa blast radius. Aplikacja notatkowa często działa cały dzień, a treść synchronizuje się automatycznie.

Co zrobić teraz

Zaktualizuj SiYuan do v3.7.4 lub nowszej stabilnej wersji zawierającej poprawki. Sprawdź wersję każdego klienta desktopowego, obrazu Docker i węzła współdzielonego. Aktualizacja serwera bez aktualizacji aplikacji użytkownika nie zamyka sinków w lokalnym rendererze.

Do czasu aktualizacji nie importuj niezaufanych workspace’ów, pakietów ani PDF-ów z adnotacjami. Ogranicz współdzielenie i synchronizację do zaufanych źródeł. Nie wystarczy wyłączyć wykonywanie snippetów JavaScript, ponieważ opisywane ścieżki wykorzystują zwykłe funkcje danych i HTML.

Jeżeli to możliwe, uruchamiaj klienta na koncie bez sekretów i z ograniczonym dostępem do sieci. Organizacja może też wymusić allowlistę wersji oraz zablokować starsze obrazy w pipeline wdrożeniowym. Backup workspace’u musi być zachowany przed migracją, ale potencjalnie złośliwe dane powinny pozostać w kwarantannie.

Detekcja i odpowiedź

Przeszukaj workspace pod kątem nietypowego markup w plikach adnotacji, formułach Template, nazwach i opisach pól, szerokościach, kolorach oraz ikonach. Wartości zawierające znaczniki, cudzysłowy łamiące atrybut lub handlery zdarzeń wymagają analizy. Skanuj kopię, nie aktywny workspace otwierany przez podatny klient.

Na endpointach API monitoruj zmiany setFileAnnotation, setAttrViewColCalc, setAttrViewColWidth i podobne operacje metadanych. Koreluj je z późniejszym otwarciem dokumentu, startem procesów potomnych, dostępem do nietypowych plików i nowymi połączeniami wychodzącymi z procesu SiYuan.

Jeśli istnieją oznaki wykonania kodu, potraktuj host jak potencjalnie przejęty. Odłącz synchronizację, zabezpiecz kopię danych i logów, rotuj dostępne tokeny oraz odbuduj aplikację z zaufanego źródła. Samo usunięcie podejrzanej adnotacji nie daje pewności, że na systemie nie utrwalono dostępu.

Fakty i wnioski Breachroad

Faktem jest, że seria CVE opublikowana 15 sierpnia obejmuje wiele niesanitowanych ścieżek danych w SiYuan przed v3.7.4, a liczne rekordy mają ocenę 9,4. Advisory projektu dokumentują przepływy do innerHTML lub insertAdjacentHTML oraz konfigurację Electron z Node Integration. Nie dowodzą masowej eksploatacji w Internecie.

Wnioskiem Breachroad jest, że powtarzalność tych błędów wskazuje na problem architektury sinków i capabilities, a nie kilka niezależnych literówek. Najsilniejsza naprawa łączy centralny model renderowania niezaufanej treści z izolowanym rendererem, którego kompromitacja nie oznacza dostępu do systemu.

Jeśli organizacja buduje desktopowe narzędzia oparte na Electronie lub przetwarza współdzieloną treść, testy penetracyjne aplikacji webowych i API mogą sprawdzić przepływy danych i granice klient–backend. Dla zespołów produktowych polecamy także szkolenia cyberbezpieczeństwa dla organizacji poświęcone secure-by-design i modelowaniu skutków.

UDOSTĘPNIJ / KOPIUJ