# Filtrowanie żądań uploadu na brzegu: szanse i ryzyka

> Filtrowanie multipart/form-data na proxy lub w WAF: kiedy nieoficjalny środek przejściowy pomaga, co psuje i jak wdrożyć go bezpiecznie.

Źródło: https://phpsos.de/pl/blog/upload-anfragen-am-rand-filtern/  
Stan: 25.10.2026  
Dostawca: PHP SOS, Pomoc awaryjna PHP i bezpieczeństwo serwerów. Natychmiastowa pomoc przez WhatsApp: https://wa.me/491736494914?text=Dzie%C5%84%20dobry%2C%20PHP%20SOS%2C%20potrzebujemy%20pomocy%20z%20naszym%20serwerem%20PHP.%20Firma%3A%20%E2%80%A6%20Strona%20internetowa%3A%20%E2%80%A6

**Krótko:** Filtrowanie żądań uploadu na brzegu oznacza odrzucanie na proxy, w serwerze WWW lub w WAF żądań POST typu `multipart/form-data`, jeśli nie trafiają na znaną ścieżkę uploadu. Autorzy branżowi proponują to jako tymczasowy, nieoficjalny środek przeciw PHP2Shell. Może zepsuć formularze i uploady i nigdy nie zastępuje aktualizacji. Proszę postępować w trzech krokach: rejestrować, ustalić wyjątki, dopiero potem blokować, ze stałym terminem końcowym.

## Propozycja z dyskusji branżowej

Dopóki serwer nie jest załatany, operatorzy szukają wszystkiego, co zmniejsza ryzyko. W dyskusji branżowej o PHP2Shell pojawiła się przy tym propozycja: zezwalać na żądania POST w formacie `multipart/form-data`, czyli formacie uploadów plików i niektórych formularzy, tylko tam, gdzie aplikacja rzeczywiście ich oczekuje. Wszystkie pozostałe są odrzucane na proxy lub w Web Application Firewall.

Ważna jest ocena. Propozycja nie pochodzi od php.net, lecz od autorów branżowych i jest wyraźnie przewidziana jako środek tymczasowy. php.net podaje własne środki przejściowe, zebrane na stronie [Środki doraźne, gdy nie mogą Państwo jeszcze załatać](https://phpsos.de/pl/php2shell/sofortmassnahmen-ohne-patch/). Filtr może je uzupełnić, ale nie zastąpić.

Opisujemy tutaj, jak wdrożyć go kontrolowanie. Szczegóły, dlaczego miałby pomagać przeciw jakim atakom, pomijamy świadomie.

## Co filtr daje i gdzie szkodzi

Myśl przewodnia to zmniejszenie powierzchni ataku. Większość podstron strony nie potrzebuje uploadów plików. Jeśli takie żądania przyjmuje już tylko kilka znanych ścieżek, duża część możliwych prób ataku w ogóle nie dociera do PHP.

Odwrotna strona jest równie jasna. Każda funkcja, która wysyła żądania multipart i nie znajduje się na liście wyjątków, przestaje działać. Dotyczy to nie tylko oczywistych formularzy uploadu.

| Funkcja | Często używa multipart/form-data | Ryzyko przy blokowaniu |
|---|---|---|
| Formularze kontaktowe i aplikacyjne z załącznikiem | tak | żądania giną |
| Zarządzanie mediami w panelu CMS | tak | redakcja nie może przesyłać obrazów |
| Import produktów lub klientów | tak | interfejsy psują się po cichu |
| Formularze bez załącznika | czasami | zależnie od kreatora formularzy |
| Interfejsy i zwrotne informacje usług zewnętrznych | rzadko, ale możliwe | awaria wychodzi na jaw późno |

Dochodzi problem zasadniczy: Cloudflare, który sam wdrożył reguły ochronne przeciw PHP2Shell, ostrzega, że same reguły oparte na danych żądania nie wystarczają. Jak myśleć o obu poziomach łącznie, opisuje artykuł [WAF albo aktualizacja: dlaczego potrzebne jest jedno i drugie](https://phpsos.de/pl/blog/waf-oder-update/).

## Krok 1: najpierw rejestrować, potem blokować

Zanim cokolwiek zablokują Państwo, ustalają, jakie ścieżki w ogóle otrzymują żądania multipart. Standardowe logi nie pokazują typu zawartości. Dla Nginx zakładają więc Państwo tymczasowo własny dziennik:

```nginx
# w bloku http
map $uri $upload_pfad {
    default 0;
    ~^/kontakt/upload\.php$ 1;
    ~^/admin/medien/ 1;
}

map "$request_method:$upload_pfad:$content_type" $multipart_fremd {
    default 0;
    "~*^POST:0:multipart/form-data" 1;
}

log_format multipart '$time_iso8601 $remote_addr "$request" "$content_type" $status';

# w bloku server
# Uwaga: access_log w bloku server zastępuje odziedziczony dziennik,
# dlatego zwykły log podać tutaj ponownie.
access_log /var/log/nginx/access.log combined;
access_log /var/log/nginx/multipart-test.log multipart if=$multipart_fremd;
```

Wpisy w `$upload_pfad` są przykładami. Proszę zacząć od pustej listy wyjątków, wtedy dziennik testowy pokazuje wszystkie żądania POST multipart. W Apache to samo osiąga się zmienną środowiskową:

```apache
# w VirtualHost
SetEnvIfNoCase Content-Type "^multipart/form-data" ist_multipart
CustomLog ${APACHE_LOG_DIR}/multipart-test.log combined env=ist_multipart
```

Dziennik proszę pozostawić włączony na kilka dni, najlepiej w okresie, w którym aktywni byli także redakcja, kandydaci i interfejsy.

## Krok 2: ustalić wyjątki i blokować kontrolowanie

Z dziennika testowego wyprowadzają Państwo ścieżki, które legalnie potrzebują uploadów. Listę proszę uzgodnić z osobami odpowiedzialnymi: kto prowadzi treści, jakie są formularze, które usługi wysyłają dane?

1. Sporządzić listę wyjątków z dziennika i zapytań, wpisać ją do `$upload_pfad` lub do wierszy `RewriteCond`.
2. Aktywować filtr najpierw w środowisku testowym lub w spokojnym oknie czasowym.
3. Samodzielnie przetestować wszystkie formularze, uploady i ścieżki zamówień.
4. Monitorować log błędów pod kątem odrzuconych żądań (status 403) i w razie potrzeby uzupełniać listę.
5. Ustalić termin końcowy: po aktualizacji PHP i restarcie wszystkich procesów roboczych filtr zostaje ponownie usunięty.

W Nginx dodają Państwo w tym celu blokadę w bloku serwera:

```nginx
# w bloku server, po ocenie fazy rejestrowania
if ($multipart_fremd) {
    return 403;
}
```

W Apache zadanie przejmuje `mod_rewrite`. Według dokumentacji Apache kilka warunków łączy się za pomocą AND:

```apache
RewriteEngine On
RewriteCond %{REQUEST_METHOD} =POST
RewriteCond %{HTTP:Content-Type} ^multipart/form-data [NC]
RewriteCond %{REQUEST_URI} !^/kontakt/upload\.php$
RewriteCond %{REQUEST_URI} !^/admin/medien/
RewriteRule ^ - [F]
```

Jeśli korzystają Państwo z CDN lub chmurowej WAF, tę samą logikę można często odwzorować jako własną regułę. Także tam obowiązuje: najpierw w trybie rejestrowania, potem blokowanie.

> **Ważne:**
> Filtr nie zastępuje aktualizacji PHP i nie jest powodem do jej odkładania. PHP2Shell jest usunięte wyłącznie dzięki PHP 8.5.12, 8.4.27, 8.3.36, 8.2.35 lub potwierdzonemu backportowi, a następnie restartowi wszystkich procesów PHP.

## Właściwa ocena tego środka

Filtr uploadów należy do szeregu innych propozycji, które obecnie krążą. Niektóre są sensowne, inne szkodliwe. Przegląd tego, jakie rady autorzy branżowi odrzucają, na przykład blokowanie wszystkich żądań z ciasteczkiem sesji, daje artykuł [Niebezpieczne fałszywe rady dotyczące PHP2Shell](https://phpsos.de/pl/blog/gefaehrliche-falschtipps/).

Jak PHP wewnętrznie przetwarza uploady i dlaczego format `multipart/form-data` odgrywa przy tym szczególną rolę, wyjaśnia artykuł [Jak PHP przetwarza uploady plików](https://phpsos.de/pl/php/datei-uploads-intern/). Dla większości firm najważniejszym krokiem nie jest jednak filtr, lecz jasny termin aktualizacji.

## Wniosek: narzędzie na dni, a nie na miesiące

Filtr uploadów na brzegu jest typowym przykładem środka awaryjnego: może zmniejszyć powierzchnię ataku w okresie przejściowym, ale ma skutki uboczne i nie ma oficjalnego poparcia php.net. Zastosowany właściwie, z fazą rejestrowania, uzgodnioną listą wyjątków, testami i stałym terminem końcowym, jest do przyjęcia. Bez tych kroków ryzykują Państwo utracone aplikacje, zablokowane redakcje i ciche błędy interfejsów.

Dlatego decyzję proszę podjąć świadomie i odnotować, kto i kiedy ją podjął. I pamiętać o kolejności: najpierw jest aktualizacja PHP z restartem wszystkich procesów roboczych, środki przejściowe php.net pomagają przetrwać czas do niej, a filtr jest co najwyżej dodatkową warstwą.

## Jak konkretnie pomaga PHP SOS?

- **Ocena sytuacji:** wyjaśniamy, czy filtr uploadów w Państwa sytuacji w ogóle ma sens, czy aktualizacja jest możliwa szybciej.
- **Rejestrowanie i analiza:** konfigurujemy fazę rejestrowania i wyprowadzamy listę wyjątków z rzeczywistych wywołań.
- **Kontrolowane blokowanie:** aktywujemy filtr, testujemy formularze i ścieżki zamówień oraz monitorujemy odrzucone żądania.
- **Czyste wycofanie:** w ramach [WAF i wirtualnego łatania](https://phpsos.de/pl/leistungen/waf-virtuelles-patching/) po aktualizacji ponownie usuwamy filtr.


## Częste pytania

**Czy filtrowanie żądań multipart jest oficjalnym zaleceniem php.net?**  
Nie. php.net podaje inne środki przejściowe, na przykład limity dla post_max_size i wyłączenie session.upload_progress. Filtrowanie na brzegu to propozycja z artykułów branżowych, wyraźnie przewidziana tylko jako środek tymczasowy.

**Jakie funkcje mogą przestać działać z powodu filtra?**  
Wszystko, co wysyła pliki lub formularze w formacie multipart i nie znajduje się na Państwa liście wyjątków: formularze kontaktowe z załącznikiem, formularze aplikacyjne, zarządzanie mediami w CMS, funkcje importu, niektóre interfejsy i zwrotne informacje o płatnościach. Dlatego przed blokowaniem następuje faza rejestrowania.

**Czy filtr zastępuje aktualizację PHP?**  
Nie. Co najwyżej zmniejsza powierzchnię ataku w okresie przejściowym. Cloudflare sam zwraca uwagę, że same reguły oparte na danych żądania nie wystarczają. PHP2Shell jest usunięte wyłącznie dzięki załatanej wersji PHP i restartowi wszystkich procesów roboczych.

**Czy zamiast tego mam blokować żądania z PHPSESSID?**  
Nie. Ta krążąca rada jest wyraźnie odrzucana przez autorów branżowych. Paraliżuje logowania i koszyki, nie dając wiarygodnej ochrony.

## Źródła

- [php.net: komunikaty bezpieczeństwa](https://www.php.net/)
- [Nginx: ngx_http_map_module](https://nginx.org/en/docs/http/ngx_http_map_module.html)
- [Apache: mod_rewrite](https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html)
- [Blog Cloudflare](https://blog.cloudflare.com/)
