Luka w Node.js: łatka Node2Shell i sprawdzanie wersji Node.js (WordPress)

Informacja o linkach partnerskich v3.1
Informacja o linkach partnerskich v3.2 (wersja mobilna)
Środowisko testowe Rodzina RHELAlmaLinux 9.8Nginx + Apache · WordPress 7.1.3Sprawdzono 2026-10-23

Node2Shell to przydomek CVE-2026-111497, luki w Node.js, na którą łatkę wydano 21 października 2026 r.; oficjalny tytuł opisuje błąd zapisu poza granicami bufora w dekoderze Brotli od Google. Ponieważ rozpakowanie spreparowanych danych Brotli może prowadzić do zdalnego wykonania kodu, najpierw trzeba sprawdzić wersje Node.js, Bun i libbrotli na serwerze i zaktualizować je do wersji z łatką.

Na serwerze Nginx + Apache z WordPressem 7.1.3 sprawdzono, które pakiety używają dekodera Brotli i którędy zdalne żądania WordPressa przechodzą przez libbrotli.

1️⃣ Luka w Node.js Node2Shell: jak działa błąd i czego dotyczy

Nazwę Node2Shell nadał zespół badawczy firmy bezpieczeństwa Imperva w artykule z 22 października. Tytuł komunikatu na nodejs.org brzmi [Brotli decoder out-of-bounds write permits remote code execution]. Błąd tkwi w kodzie źródłowym dekodera Google Brotli wbudowanego w Node.js (c/dec/decode.c), więc poprawki w kodzie aplikacji go nie zablokują.

Według wpisu NVD dekoder Google Brotli w wersjach od 1.0.3 do 1.2.0 podczas rozpakowywania spreparowanego strumienia zapisuje dane za końcem bufora i uszkadza sąsiednią pamięć stanu dekodera. Przez ten błąd zdalny atakujący bez logowania może odczytać zawartość pamięci serwera, przerwać działanie usługi i wykonać dowolny kod.

Ocen wagi są dwie. Komunikat na nodejs.org nadał poziom High, a Google, które wydało CVE, przyznało 9,2 (Critical) w skali CVSS 4.0. Według stanu na 23 października NVD nie zakończyło jeszcze własnej analizy, więc wyniku NVD jeszcze nie ma. Typy słabości to niesprawdzana wartość zwracana (CWE-252) i zapis poza granicami bufora (CWE-787).

Według komunikatu bezpieczeństwa na nodejs.org luka dotyczy wszystkich wspieranych linii Node.js (22.x, 24.x i 26.x), a wersje z łatką to 22.23.4, 24.22.1 i 26.12.1. Ten sam komunikat podaje, że linie bez wsparcia przy każdym komunikacie bezpieczeństwa zawsze uznaje się za podatne.

Podatny jest każdy program, który używa tego samego dekodera, także poza Node.js. 21 października Google wydało trzy wersje biblioteki Brotli z poprawką tej samej CVE: 1.0.10, 1.1.1 i 1.2.1. Bun 22 października umieścił Brotli na liście poprawek bezpieczeństwa w ogłoszeniu wersji 1.4.4, a zgłoszenie w repozytorium podaje, że ta wersja zawiera poprawkę aktualizującą brotli.

celWersje podatneWersja z poprawkąŹródło
Node.jsWszystkie wspierane linie 22.x · 24.x · 26.x · linie bez wsparcia22.23.4 · 24.22.1 · 26.12.1Komunikat bezpieczeństwa nodejs.org (2026-10-21)
Biblioteka Brotli od Google1.0.3 ~ 1.2.01.0.10 · 1.1.1 · 1.2.1Wpis NVD · wydania google/brotli (2026-10-21)
BunBrotli na liście poprawek bezpieczeństwa w ogłoszeniu wersji 1.4.41.4.4Ogłoszenie Bun (2026-10-22)
Pakiet libbrotli z dystrybucjiPakiety zbudowane na Brotli od 1.0.3 do 1.2.0Wersja podana w komunikacie bezpieczeństwa dystrybucji (na 2026-10-23 jeszcze jej nie ma)Strona trackera bezpieczeństwa każdej dystrybucji

Sam Node.js nie rozpakowuje z własnej inicjatywy odebranych danych Brotli. Według komunikatu bezpieczeństwa firmy hostingowej Vercel narażone są miejsca, w których aplikacja lub biblioteka rozpakowuje skompresowane dane z zewnątrz. Przykładem jest wbudowany fetch(), gdy odbiera odpowiedź br, oraz Express 5 lub body-parser 2, gdy rozpakowują treść żądania br; domyślny serwer HTTP, który tylko odbiera dane, niczego nie rozpakowuje.

Według stanu na 23 października nie potwierdzono rzeczywistego wykorzystania luki. Tej CVE nie ma w katalogu znanych wykorzystywanych podatności CISA (KEV, wersja z 21 października). Etap wykorzystania, który CISA nadaje we wpisie CVE, zmienił się 23 października na [publiczny proof of concept (PoC)].

To, gdzie znajduje się dekoder, decyduje o tym, co trzeba zrobić. Oficjalne binaria Node.js mają dekoder wbudowany w plik wykonywalny, ale są też buildy korzystające z systemowej libbrotli, jak pakiet nodejs w Debianie. Dystrybucje Linuksa instalują ten sam kod źródłowy jako pakiet libbrotli, z którego wspólnie korzystają programy takie jak curl.

2️⃣ Witryny WordPress i PHP też są zagrożone: droga, którą zdalne żądania rozpakowują odpowiedzi przez libbrotli

Także na serwerze WordPress bez Node.js ten sam dekoder jest zainstalowany jako pakiet libbrotli. Według stanu na 23 października ani WordPress, ani curl, ani PHP nie wypowiedziały się oficjalnie o tej CVE i nie ma jej też na oficjalnej liście podatności curl. Dlatego ta sekcja potwierdza tylko strukturę na podstawie kodu rdzenia, dokumentacji curl i pomiarów na serwerze testowym.

Na zmierzonym serwerze Nginx + Apache bibliotekę dekodera (libbrotlidec) wymagało pięć pakietów, a pakietem powiązanym z WordPressem jest libcurl.

rpm -q --whatrequires 'libbrotlidec.so.1()(64bit)' | sed 's/-[0-9].*//'
freetype
brotli-devel
libjxl
libcurl
libsoup

libcurl wymaga libbrotli do rozpakowywania skompresowanych odpowiedzi HTTP. Według oficjalnej dokumentacji curl libcurl zbudowana z biblioteką brotli automatycznie rozpakowuje odpowiedzi z nagłówkiem Content-Encoding równym br. Tę libcurl bezpośrednio wywołuje rozszerzenie curl w PHP.

ldd /usr/lib64/libcurl.so.4 | grep brotli
    libbrotlidec.so.1 => /lib64/libbrotlidec.so.1 (0x00007f32803ed000)
    libbrotlicommon.so.1 => /lib64/libbrotlicommon.so.1 (0x00007f327f858000)
php -i | grep BROTLI
BROTLI => Yes

Wersja libcurl używana przez WordPressa widnieje w wierszu [Wersja cURL] po rozwinięciu sekcji [Serwer] na zakładce [Informacja] w [Narzędzia › Stan witryny] w panelu administracyjnym. Ten wiersz nie pokazuje, czy brotli jest obsługiwane, więc sprawdza się to poleceniami na serwerze, jak wyżej.

Ekran Stan witryny, zakładka Informacja: menu po lewej Narzędzia › Stan witryny oraz wiersze Architektura serwera, Serwer webowy, Wersja PHP, PHP SAPI i Wersja cURL w sekcji Serwer — sprawdzenie w wierszu Wersja cURL wersji libcurl, czyli drogi luki Node.js Node2Shell po stronie WordPressa (WordPress 7.1.3)

Wiersz [Wersja cURL] na obrazie pokazuje wersję libcurl razem z biblioteką SSL, z którą ją zbudowano. Według dokumentacji curl br jest obsługiwany od wersji 7.57.0; jeśli ta wartość jest niższa, libcurl nie rozpakuje odpowiedzi br. Jeśli jest równa lub wyższa, sprawdza się poleceniami na serwerze, czy brotli znalazło się w buildzie.

Biblioteka Requests w rdzeniu WordPressa przy żądaniach do zewnętrznych adresów ustawia wartość [CURLOPT_ENCODING] uchwytu curl na pusty ciąg. Według dokumentacji curl pusty ciąg oznacza akceptowanie wszystkich metod kompresji obsługiwanych przez daną libcurl. Jeśli więc drugi serwer odeśle odpowiedź skompresowaną br, rozpakuje ją libbrotli na serwerze WordPress.

grep -n CURLOPT_ENCODING wp-includes/Requests/src/Transport/Curl.php
110:            curl_setopt($this->handle, CURLOPT_ENCODING, '');
212:            curl_setopt($this->handle, CURLOPT_ENCODING, 'none');

Wiersz 110 to wartość domyślna dla wszystkich żądań, a wiersz 212 wykonuje się tylko wtedy, gdy żądanie, którego nie udało się rozpakować, jest wysyłane ponownie bez kompresji. Z zewnątrz nie da się tego uruchomić bezpośrednio; najpierw musiałby zostać przejęty serwer, z którego WordPress pobiera odpowiedzi, np. przy sprawdzaniu aktualizacji rdzenia i wtyczek, w oEmbed lub w kanałach RSS.

🧩 Przebieg ataku Node2Shell
Diagram objaśniający
①Skompresowane dane z zewnątrzTreść żądania skompresowana br albo odpowiedź innego serwera
②Aplikacja rozpakowuje je dekoderem BrotliNode.js fetch() · Express 5 · Bun fetch() · WordPress przez libcurl → libbrotli
③Błąd dekodera BrotliSpreparowany strumień zapisuje dane za końcem buforaCVE-2026-111497
④Wykonanie kodu na serwerzeWyciek pamięci · przerwa w działaniu usługi · przejęcie serwera
✅ Poprawione wersje blokują ten przebiegNode.js 22.23.4 · 24.22.1 · 26.12.1Bun 1.4.4Brotli 1.0.10 · 1.1.1 · 1.2.1

Przebieg zaczyna się od danych z zewnątrz skompresowanych br. Błąd zostaje wywołany na etapie, gdy fetch() w Node.js, Express 5, fetch() w Bun albo libbrotli wywoływana przez libcurl w WordPressie rozpakowuje te dane. Skutkiem jest wykonanie kodu na serwerze. Wersje z łatką blokują ten przebieg, więc trzeba zastąpić dekoder wersją z łatką.

Moduł mod_brotli w Apache linkuje tylko bibliotekę kodera (libbrotlienc), która kompresuje odpowiedzi, więc konfiguracja włączająca kompresję tym modułem nie leży na drodze błędu dekodera.

ldd /usr/lib64/httpd/modules/mod_brotli.so | grep brotli
    libbrotlienc.so.1 => /lib64/libbrotlienc.so.1 (0x00007f34b4b79000)
    libbrotlicommon.so.1 => /lib64/libbrotlicommon.so.1 (0x00007f34b4a79000)

3️⃣ Sprawdzanie wersji Node.js: czy na serwerze są Node.js, Bun i libbrotli i w jakich wersjach

Pracę zaczyna się od spisania, co jest zainstalowane na serwerze. W przypadku Node.js wersję sprawdza się poleceniem [node -v]; jeśli wartość jest niższa niż 22.23.4, 24.22.1 lub 26.12.1 dla danej linii, wersja jest podatna.

Twoje środowiskoPolecenie sprawdzająceCo zostaje naprawione
Instalator z nodejs.org · nvm · oficjalny obraz Docker[node -v]Sam Node.js (22.23.4 · 24.22.1 · 26.12.1)
nodejs z dystrybucji · wiersz libbrotli w ldd[ldd $(command -v node)]Pakiet libbrotli
nodejs z dystrybucji · wynik ldd 0[ldd $(command -v node)]Pakiet nodejs (po komunikacie bezpieczeństwa dystrybucji)
Node.js Selector w hostingu współdzielonym (CloudLinux alt-nodejs)Komunikat dostawcy · numer release pakietuPakiet udostępniony przez dostawcę + ponowne uruchomienie aplikacji
Bun[bun --version]Bun 1.4.4 lub nowszy
Bez Node.js (tylko WordPress)Sprawdzenie libcurl przez [ldd]Pakiet libbrotli + restart php-fpm · do tego czasu zabezpieczenie tymczasowe
Hosting zarządzanyKomunikat dostawcy · zapytanie do pomocy technicznejPakiety aktualizowane przez dostawcę

Na komputerze (Windows lub macOS) instaluje się ponownie instalatorem wersji z łatką z nodejs.org; w nvm sprawdza się wersję poleceniem [nvm ls], a potem instaluje ponownie według numeru linii, np. [nvm install 24]. Tagi 22, 24 i 26 oficjalnego obrazu Docker node przebudowano 22 października z wersjami z łatką, więc trzeba ponownie pobrać obraz, zbudować go i wdrożyć. Komunikat Vercel zaleca też aktualizację do wersji z łatką samodzielnie budowanych obrazów kontenerów, środowisk CI i lokalnych środowisk programistycznych.

Na serwerze, na którym zainstalowano Node.js ze strumienia dnf module, [node -v] pokazuje wersję z linii tego strumienia; nawet przy tej samej linii trzeba zaktualizować, jeśli końcowe cyfry nie sięgają wersji z łatką.

node -v
v24.xx.x

To, czy Node.js używa systemowej libbrotli, czy wbudowanego dekodera, sprawdza się przez [ldd]. Jeśli w wyniku jest wiersz libbrotlidec, build korzysta z biblioteki współdzielonej; jeśli wynik to 0, jak niżej, dekoder jest wbudowany i błąd usuwa dopiero aktualizacja samego Node.js.

ldd $(command -v node) | grep -c brotli
0

W Bun wersję sprawdza się poleceniem [bun --version], a jeśli jest niższa niż 1.4.4, trzeba ją zaktualizować.

W systemach RPM wersję pakietu libbrotli sprawdza się poleceniem [rpm -q libbrotli]. Numery wersji pakietów nadaje dystrybucja, więc nie porównuje się ich bezpośrednio z numerami wydań Google, tylko z wersją, którą komunikat bezpieczeństwa dystrybucji wyda dla tego numeru CVE.

rpm -q libbrotli
libbrotli-1.0.x-x.el9_x.x86_64

To, czy dystrybucja wydała komunikat, sprawdza się poleceniem [dnf updateinfo info --cve CVE-2026-111497]. Pusty wynik oznacza, że w tym repozytorium nie ma jeszcze komunikatu dla tej CVE.

dnf updateinfo info --cve CVE-2026-111497

Pakiet, który przejmuje tylko poprawkę bez zmiany numeru wersji, zostawia numer CVE w dzienniku zmian. Dlatego sprawdza się to poleceniem [rpm -q --changelog libbrotli | grep CVE-2026-111497]; jeśli pojawi się wiersz, pakiet ma łatkę.

rpm -q --changelog libbrotli | grep CVE-2026-111497

Według stanu na 23 października pakiety libbrotli w Debianie, Ubuntu, Red Hat i AlmaLinux nie mają jeszcze wersji z łatką dla tej CVE. Alpine wydał wersję z łatką tylko dla pakietu nodejs; źródłem są strony trackerów bezpieczeństwa poszczególnych dystrybucji. Na razie kolejność jest więc taka: obserwować komunikat bezpieczeństwa dystrybucji i zaktualizować, gdy się pojawi.

W Debianie i Ubuntu pakiet nazywa się libbrotli1, a te same punkty sprawdzono na serwerze testowym Debian 12 u dostawcy hostingu zarządzanego. Również na tym serwerze libcurl linkowała libbrotlidec, a rozszerzenie curl w PHP obsługiwało brotli. Dziennik zmian wyświetla się poleceniem [zcat /usr/share/doc/libbrotli1/changelog.Debian.gz | grep CVE-2026-111497].

dpkg -l libbrotli1 | tail -1
ii  libbrotli1:amd64 1.1.0-2+0~20240305.8+debian12~1.gbp62df71 amd64        library implementing brotli encoder and decoder (shared libraries)
ldd /usr/lib/x86_64-linux-gnu/libcurl.so.4 | grep brotli
    libbrotlidec.so.1 => /lib/x86_64-linux-gnu/libbrotlidec.so.1 (0x00007fa2baac6000)
    libbrotlicommon.so.1 => /lib/x86_64-linux-gnu/libbrotlicommon.so.1 (0x00007fa2b9cb9000)

4️⃣ Aktualizacja Node.js: przejście na wersję z łatką i ponowne sprawdzenie

W hostingu zarządzanym i współdzielonym pakiety serwera aktualizuje dostawca, więc to, czy Node.js i libbrotli mają łatkę, sprawdza się w komunikatach dostawcy lub przez pomoc techniczną. Przy samodzielnie prowadzonym serwerze Node.js aktualizuje się do wersji z łatką z komunikatu nodejs.org, a Bun poleceniem [bun upgrade] do wersji 1.4.4 lub nowszej.

Node.js zainstalowany ze strumienia modułów dystrybucji aktualizuje się poleceniem w rodzaju [dnf upgrade nodejs], gdy wersja z łatką trafi do tego repozytorium. Na serwerze, na którym Node.js pobrano i zainstalowano bezpośrednio z nodejs.org, zastępuje się go wersją z łatką z tego samego miejsca. Linie bez wsparcia nie dostają wersji z łatką, więc trzeba przejść na wspieraną linię: 22, 24 lub 26.

Node.js Selector w hostingu współdzielonym (CloudLinux alt-nodejs) ma własną kopię brotli, więc aktualizacja systemowej libbrotli go nie naprawia. Według komunikatu CloudLinux nowe binarium działa dopiero po przejściu na pakiet udostępniony przez dostawcę i ponownym uruchomieniu aplikacji. Ten sam komunikat podaje, że w wersjach bez wsparcia wartość [node --version] się nie zmienia, więc sprawdza się numer release pakietu.

Pakiet libbrotli aktualizuje się, gdy pojawi się komunikat bezpieczeństwa dystrybucji, a potem uruchamia ponownie procesy, które mają bibliotekę w pamięci, aby przeszły na nową bibliotekę. Biblioteki współdzielone są wczytywane przy starcie procesu, więc na serwerze WordPress restart php-fpm należy do tego samego kroku.

Po aktualizacji sprawdza się, czy [node -v] pokazuje wersję z łatką lub nowszą, a [rpm -q libbrotli] wersję z komunikatu dystrybucji. To, czy numer CVE trafił do dziennika zmian, sprawdza się poleceniem [rpm -q --changelog libbrotli | grep CVE-2026-111497]. Po restarcie php-fpm warto sprawdzić też stan usługi i odpowiedź witryny.

systemctl is-active php-fpm
active
curl -s -o /dev/null -w '%{http_code}\n' 'https://example.com/?r=1'
200

5️⃣ Tymczasowe zabezpieczenie przed łatką: wyłączenie rozpakowywania br w zdalnych żądaniach WordPressa

Strona CVE Red Hat zaleca takie skonfigurowanie aplikacji, aby nie akceptowały kompresji br z niezaufanych źródeł albo nie rozpakowywały jej automatycznie.

Drogę po stronie WordPressa można zablokować już teraz, jeszcze przed wydaniem pakietów z łatką. WordPress udostępnia hook [http_api_curl], który przy każdym zdalnym żądaniu przekazuje uchwyt curl. Ustawienie w nim [CURLOPT_ENCODING] na null wyłącza automatyczne rozpakowywanie w libcurl.

Umieszczenie poniższego pliku w folderze [wp-content/mu-plugins/] obejmuje wszystkie zdalne żądania; nazwa pliku jest przykładowa. Aby to cofnąć, wystarczy usunąć ten plik.

<?php
// no-brotli-decode.php — WordPress zdalny w żądaniach libcurl Automatyczny rozpakowywanie Wyłączone(libbrotli łatka wersja wyjdzie do)
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}
add_action( 'http_api_curl', function ( $handle ) {
    curl_setopt( $handle, CURLOPT_ENCODING, null );
}, 99 );

Łatwo pomyśleć, że ograniczenie [CURLOPT_ENCODING] do [gzip, deflate] wyklucza br. Ta wartość usuwa br tylko z nagłówka Accept-Encoding żądania; jeśli drugi serwer odpowie w br, libcurl i tak rozpakuje to, co otrzyma. Na witrynie testowej pobrano httpbin.org/brotli z tą samą wartością i odpowiedź z Content-Encoding br została rozpakowana i dała się przeczytać.

Według dokumentacji curl jedyną wartością wyłączającą automatyczne rozpakowywanie jest null; przy null nagłówek Accept-Encoding nie jest wysyłany, a odebrana treść nie jest rozpakowywana. Odpowiedzi gzip i deflate rozpakowuje sama biblioteka Requests w WordPressie i pozostają czytelne; nierozpakowane zostają tylko odpowiedzi br.

Ten hook WordPress podpiął pod punkt [curl.before_send], który Requests wywołuje tuż przed uruchomieniem curl. Jest wywoływany w wierszu 174 pliku Curl.php, a curl wykonuje się w wierszu 205, więc pusty ciąg ustawiony przez rdzeń w wierszu 110 zostaje w międzyczasie nadpisany.

To, czy zmiana działa, sprawdza się poniższym plikiem testowym. httpbin.org to adres testowy, który zwraca nagłówki odebranego żądania, a także odpowiedzi skompresowane br i gzip, więc od razu widać, co WordPress wysyła i co rozpakowuje.

<?php
// br-check.php — WordPress zdalny żądanie jaki kompresja wysyła czy rozpakowuje Sprawdź(httpbin.org testowy Adres)
$h = json_decode( wp_remote_retrieve_body( wp_remote_get( 'https://httpbin.org/headers' ) ), true );
echo 'Accept-Encoding: ', isset( $h['headers']['Accept-Encoding'] ) ? $h['headers']['Accept-Encoding'] : '(none)', PHP_EOL;
foreach ( array( 'brotli', 'gzip' ) as $p ) {
    $r = wp_remote_get( 'https://httpbin.org/' . $p );
    $readable = strpos( wp_remote_retrieve_body( $r ), ': true' ) !== false;
    echo $p, ': Content-Encoding=', wp_remote_retrieve_header( $r, 'content-encoding' ), ' / ', strlen( wp_remote_retrieve_body( $r ) ), ' bytes / ', ( $readable ? 'readable' : 'not decoded' ), PHP_EOL;
}

Przed dodaniem pliku Accept-Encoding zawiera br, a odpowiedź br zostaje rozpakowana i jest czytelna.

wp eval-file br-check.php
Accept-Encoding: deflate, gzip, br
brotli: Content-Encoding=br / 316 bytes / readable
gzip: Content-Encoding=gzip / 317 bytes / readable

Po dodaniu pliku nagłówek Accept-Encoding znika, odpowiedź br pozostaje nierozpakowana, a odpowiedź gzip nadal jest czytelna.

wp eval-file br-check.php
Accept-Encoding: (none)
brotli: Content-Encoding=br / 199 bytes / not decoded
gzip: Content-Encoding=gzip / 272 bytes / readable

Po aktualizacji do pakietu libbrotli z łatką z dystrybucji i restarcie php-fpm usuwa się ten plik, aby przywrócić pierwotny stan.

🔢 FAQ & polecane treści

Automatyczne aktualizacje WordPressa obejmują tylko rdzeń, wtyczki, motywy i tłumaczenia; libbrotli i Node.js to pakiety zainstalowane na serwerze, więc aktualizuje je administrator serwera albo dostawca hostingu. Dopiero po aktualizacji i restarcie php-fpm zdalne żądania WordPressa są obsługiwane przez nową bibliotekę.

Niezależnie od tego, czy wtyczka korzysta z WordPress HTTP API, czy wywołuje funkcje curl bezpośrednio, przechodzi przez tę samą libcurl. Naprawić trzeba pakiet libbrotli na serwerze; do czasu wydania wersji z łatką automatyczne rozpakowywanie zdalnych żądań WordPressa można wyłączyć ustawieniem z sekcji 5️⃣. Według dokumentacji curl kod, który wywołuje funkcje curl bezpośrednio i nie ustawia [CURLOPT_ENCODING], nie rozpakowuje automatycznie skompresowanych odpowiedzi. Kod, który wywołuje je bezpośrednio i ustawia tę wartość na pusty ciąg, znajduje się poza hookiem [http_api_curl], więc żądania tej wtyczki sprawdza się osobno.

We wpisach CVE-2026-111497 w NVD i cve.org (CNA Google) podano miejsce błędu (c/dec/decode.c), podatne wersje i typ słabości. Informacje o poprawce zawierają noty wydań google/brotli v1.2.1, v1.1.1 i v1.0.10. Szczegółów pozwalających odtworzyć atak nie umieszczono w tym artykule.

ℹ️ Informacja o linkach partnerskich
Treści tej witryny zawierają linki partnerskie. Jeśli odwiedzający kupi produkt lub usługę przez taki link, witryna otrzymuje od sprzedawcy prowizję. Kwota płacona przy tym przez kupującego (podczas promocji spada↓) nie wzrasta. Podane ceny, rabaty i dostępność odnoszą się do chwili pisania i mogą różnić się od stanu faktycznego, dlatego przed zakupem sprawdź je u sprzedawcy. Produkty wybieramy i oceniamy według własnych kryteriów, a prowizja nie wpływa ani na kolejność prezentacji, ani na treść ocen.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Wymagane pola są oznaczone *

Prove your humanity: 7   +   6   =