Sklep z plikami do pobrania ma jedno założenie: plik dostaje ten, kto zapłacił. Jeśli to założenie nie jest prawdziwe, nie jest prawdziwy cały model sprzedaży - a wygląda to dokładnie tak samo jak sklep, w którym wszystko działa.
Skąd bierze się dziura
WooCommerce domyślnie trzyma pliki w wp-content/uploads/woocommerce_uploads/ i wrzuca tam plik .htaccess z regułą blokującą dostęp. To rozsądne rozwiązanie z jednym zastrzeżeniem: plik .htaccess czyta Apache. Nginx go nie czyta. W ogóle. Nie zgłasza tego błędem, nie ostrzega w panelu - po prostu wydaje plik każdemu, kto zna adres.
A adres nie jest trudny do poznania. Bywa w kodzie strony, w mailu do innego klienta, w dzienniku serwera, w historii przeglądarki na komputerze, który ktoś sprzedał.
Sprawdzenie, które zajmuje minutę
Skopiuj z panelu ścieżkę pliku przypisanego do produktu i otwórz ją w oknie prywatnym, bez zalogowania. Albo z wiersza poleceń:
curl -I https://twojsklep.pl/wp-content/uploads/woocommerce_uploads/2026/01/wtyczka.zip
Interesuje cię tylko pierwsza linia:
403albo404- katalog jest zamknięty, wszystko w porządku,200- plik właśnie się pobrał i każdy może zrobić to samo.
Sprawdź to na produkcji, a nie na kopii lokalnej - to ustawienie serwera, a serwery te zwykle się różnią. Nasza kopia lokalna stoi na nginksie i jest odsłonięta zawsze; produkcja na Apache’u oddaje 403. To ta sama klasa niespodzianki co z hakami w blokowej kasie: kod jest poprawny, a zachowanie zależy od tego, gdzie stoi. Ten sam kod, dwa różne wyniki.

Co z tym zrobić
Na nginksie: reguła w konfiguracji
Nginx trzeba poinformować osobno, bo nie dowie się tego z katalogu:
location ~* /wp-content/uploads/woocommerce_uploads/.*.(zip|pdf|mp4|epub)$ {
deny all;
return 403;
}
Na hostingu współdzielonym bez dostępu do konfiguracji zostaje prośba do działu technicznego - zwykle da się taką regułę dopisać.
Wymuszone pobieranie
W WooCommerce → Ustawienia → Produkty → Pliki do pobrania ustaw metodę na Wymuszone pobieranie. Plik idzie wtedy przez PHP, które sprawdza uprawnienia. Ma to koszt: duże pliki obciążają PHP i potrafią polec na limicie czasu wykonania, więc przy plikach wideo to nie zawsze dobry wybór.
Katalog poza stroną - ostrożnie
Przeniesienie plików poza katalog strony brzmi najbezpieczniej i czasem jest pułapką. Na hostingach współdzielonych open_basedir ogranicza PHP do konkretnych katalogów i ten „obok public_html” zwykle się w nich nie mieści. Efekt: PHP nie ma prawa odczytać pliku, a klient po zakupie dostaje błąd zamiast pobrania.
Zanim przeniesiesz katalog, sprawdź, co faktycznie jest dozwolone:
<?php echo ini_get( 'open_basedir' );
Dwie rzeczy, o których łatwo zapomnieć
Ścieżki do plików są w bazie bezwzględne. Po przeniesieniu sklepu na inny serwer produkcja potrafi szukać pliku pod ścieżką z komputera, na którym robiono kopię - i wypisać ją w komunikacie błędu razem z pełną strukturą katalogów. Warto sprowadzać ścieżkę do nazwy pliku i doklejać katalog bieżącego środowiska, zamiast przepisywać bazę.
Zatwierdzone katalogi pobierania. WooCommerce ma listę katalogów, z których wolno wydawać pliki, i nowy wpis na tej liście powstaje wyłączony. Jeśli po zmianie katalogu pobrania przestały działać, zacznij od sprawdzenia tej listy - to jedno pole wyboru, a objawia się jak poważna awaria.
Na koniec
To nie jest sprawdzenie, które robi się raz. Zmiana hostingu, przeniesienie sklepu, migracja na nowy serwer - każda z tych rzeczy potrafi cofnąć ustawienie bez żadnego sygnału. Warto zapisać sobie to jedno polecenie curl i puszczać je po każdej większej zmianie.
Nowa wtyczka? Dowiesz się pierwszy.
Premiery, poradniki i promocje - raz na jakiś czas, bez zasypywania skrzynki.