Aktuális helyzet: PHP2Shell. Két kritikus PHP-rés (CVSS 9,2) lehetővé teszi kártékony kód futtatását bejelentkezés nélkül. Javítások 2026. 10. 21. óta.Mi a teendő most →

Hogyan dolgozza fel a PHP a fájlfeltöltést

A Feltöltés gombra kattintás és az Ön kódja között a PHP-ban egy teljes feldolgozási lánc áll. Az oldal bemutatja a multipart/form-data-t, az ideiglenes fájlokat, a $_FILES-t, a korlátokat és a PHP2Shellhez fűződő kapcsolatot.

Állapot 5 perc olvasási időPHP-tudástár

Röviden: Amikor egy böngésző fájlt tölt fel, multipart/form-data formátumú POST-kérést küld, amelyben az űrlapmezők és a fájltartalmak külön részekként követik egymást. A PHP ezt a kérést maga bontja szét, minden fájlrészt ideiglenes fájlba ír az upload_tmp_dir könyvtárban, bejegyzi az adatokat a $_FILES-ba, és csak ezután indítja el az Ön szkriptjét. A szkript a move_uploaded_file() függvénnyel helyezi át a fájlt; amit nem helyez át, azt a PHP a kérés végén törli.

A fájl útja a böngészőtől a szkriptig

A döntéshozók számára elsősorban egy dolog fontos: a feltöltés nem pusztán az alkalmazás ügye. A munka nagy része a PHP-értelmezőben zajlik, még mielőtt a CMS vagy a webshop kódja egyáltalán részt venne benne. Ezért a PHP ezen részének hibái minden weboldalt érintenek, akár van feltöltési űrlapja, akár nincs.

A folyamat áttekintése:

  1. Elküldik az űrlapot method="POST" és enctype="multipart/form-data" beállítással.
  2. A webszerver elfogadja a kérést, és továbbadja a PHP-nak, az üzemmódtól függően PHP-FPM-en, mod_php-n vagy más felületen keresztül.
  3. A PHP ellenőrzi a korlátokat, például a post_max_size-t, és egy elválasztó karaktersorozat, az úgynevezett boundary mentén felbontja a tartalmat.
  4. A normál mezők a $_POST-ba kerülnek, a fájlrészeket ideiglenes fájlokba írja a PHP, és leírja őket a $_FILES-ban.
  5. Csak most indul el a szkript, ellenőrzi a fájlt, és a célhelyére helyezi.
  6. A kérés végén a PHP törli az összes ideiglenes fájlt, amelyet nem helyeztek át.

multipart/form-data: a feltöltési kérés felépítése

A feltöltési kérés tiszta szöveg, beágyazott fájladatokkal. A Content-Type fejléc megadja a boundary-t, a tartalomban pedig ez a karaktersorozat választja el egymástól az egyes részeket. Minden résznek saját fejlécsorai vannak a mezőnévvel és adott esetben a fájlnévvel. Egy erősen lerövidített, ártalmatlan példa:

POST /bewerbung HTTP/1.1
Content-Type: multipart/form-data; boundary=----trenner42

------trenner42
Content-Disposition: form-data; name="vorname"

Erika
------trenner42
Content-Disposition: form-data; name="lebenslauf"; filename="lebenslauf.pdf"
Content-Type: application/pdf

%PDF-1.7 ... Dateiinhalt ...
------trenner42--

Ebben a szövegben minden adat a feladótól származik, a fájlnév és a rész Content-Type-ja is. A PHP átveszi őket a $_FILES-ba, de hihetőségüket nem ellenőrzi.

A $_FILES tömb

A lebenslauf nevű mező esetén a $_FILES['lebenslauf'] a PHP-kézikönyv szerint ezeket a kulcsokat tartalmazza:

Kulcs Tartalom Megbízható?
name a fájl eredeti neve a feladónál nem
full_path a böngésző által jelentett útvonal, a PHP 8.1.0 óta nem
type a böngésző szerinti MIME-típus, a PHP nem ellenőrzi nem
size méret bájtban a PHP állapítja meg
tmp_name az ideiglenes fájl útvonala a szerveren a PHP adja
error a feltöltés-feldolgozás hibakódja a PHP állítja be

Szögletes zárójeles nevű mezőknél, például bilder[], minden kulcs egy tömböt tartalmaz fájlonként egy bejegyzéssel. Az alkalmazás ilyenkor például a $_FILES['bilder']['error']-on megy végig, és ugyanazzal az indexszel éri el a tmp_name-et és a name-et.

Az űrlap emellett küldhet a fájlmező előtt egy rejtett MAX_FILE_SIZE mezőt. A kézikönyv szerint ez csupán tanács a böngészőnek, amely könnyen megkerülhető. Kizárólag azokra a korlátokra támaszkodhat, amelyeket a szerver érvényesít: a PHP-ban, a webszerverben és magában az alkalmazásban.

Korlátok: a feltöltések php.ini-direktívái

Ezek a direktívák vezérlik a feltöltések feldolgozását. Az alapértékek a PHP-kézikönyvből származnak, és akkor érvényesek, ha egy php.ini nem írja felül őket.

Direktíva Alapérték Módosítható itt
file_uploads 1 csak rendszerkonfiguráció
upload_tmp_dir üres (rendszer ideiglenes könyvtára) csak rendszerkonfiguráció
upload_max_filesize 2M php.ini, pool, könyvtárkonfiguráció
post_max_size 8M php.ini, pool, könyvtárkonfiguráció
max_file_uploads 20 php.ini, pool, könyvtárkonfiguráció
enable_post_data_reading 1 php.ini, pool, könyvtárkonfiguráció

A post_max_size-nak nagyobbnak kell lennie az upload_max_filesize-nál, a memory_limit-nek pedig a kézikönyv szerint általában nagyobbnak kell lennie a post_max_size-nál. Ha az upload_tmp_dir nem írható, a PHP a rendszer ideiglenes könyvtárára tér át. Az open_basedir használatakor az ideiglenes könyvtárnak engedélyezettnek kell lennie, különben a feltöltések meghiúsulnak. A gyakorlati értékeket és következményeiket a post_max_size és upload_max_filesize ésszerű korlátozása cikk írja le.

A hibakódok helyes kiértékelése

Az error mező megmondja, mi történt a feldolgozás során. A konstansok az UPLOAD_ERR_OK (0) értéktől az UPLOAD_ERR_INI_SIZE (1), UPLOAD_ERR_FORM_SIZE (2), UPLOAD_ERR_PARTIAL (3) és UPLOAD_ERR_NO_FILE (4) értéken át az UPLOAD_ERR_NO_TMP_DIR (6), UPLOAD_ERR_CANT_WRITE (7) és UPLOAD_ERR_EXTENSION (8) értékig terjednek.

<?php
declare(strict_types=1);

$datei = $_FILES['lebenslauf'] ?? null;
if ($datei === null) {
    exit('Keine Upload-Daten, eventuell wurde post_max_size überschritten.');
}

$meldung = match ($datei['error']) {
    UPLOAD_ERR_OK => null,
    UPLOAD_ERR_INI_SIZE, UPLOAD_ERR_FORM_SIZE => 'Datei zu groß.',
    UPLOAD_ERR_NO_FILE => 'Keine Datei gewählt.',
    default => 'Upload fehlgeschlagen.',
};

if ($meldung === null && is_uploaded_file($datei['tmp_name'])) {
    $ziel = '/srv/app/uploads/' . bin2hex(random_bytes(16)) . '.pdf';
    move_uploaded_file($datei['tmp_name'], $ziel);
}

A példa csak a működési mechanizmust mutatja. A fájltípus ellenőrzését, a webgyökéren kívüli tárolást és a szkriptfuttatás tiltását a Fájlfeltöltések biztonságos megvalósítása PHP-ban útmutató írja le.

Feltöltések és PHP2Shell: mit jelentenek az átmeneti intézkedések

A CVE-2026-109618 és CVE-2026-109619 számú PHP2Shell-rések a kérés körüli feldolgozást érintik a PHP-értelmezőben. Ezért a php.net átmeneti intézkedésként többek között a post_max_size = 8M (feltöltések nélkül) vagy 32M (feltöltésekkel) értéket, az upload_max_filesize ennél alacsonyabb értékét, valamint a session.upload_progress.enabled=0 beállítást nevezi meg. Ezeket az értékeket a php.ini-be, az FPM-poolba vagy a szerverkonfigurációba kell írni, utána pedig minden workert újra kell indítani.

Szakmai szerzők emellett azt javasolják, hogy a valódi feltöltési útvonalakon kívüli multipart/form-data kéréseket a proxyn vagy a WAF-on blokkolják. Ez nem hivatalos intézkedés, és fennáll a kockázata, hogy az űrlapok elromlanak; a mérlegelést az Upload-kérések szűrése a peremen cikk írja le. Ezen intézkedések egyike sem helyettesíti a frissítést a PHP 8.5.12, 8.4.27, 8.3.36 vagy 8.2.35 verzióra.

Hogyan segít konkrétan a PHP SOS?

  • Megállapítjuk, hogy az Ön weboldalai közül melyeknek van ténylegesen szükségük feltöltésekre, és mely útvonalakon.
  • Poolonként beállítjuk a korlátokat és az átmeneti intézkedéseket, újraindítjuk az összes workert, és teszteljük az űrlapokat.
  • Ellenőrizzük a feltöltési könyvtárakat futtatható fájlok szempontjából, és a szerverkeményítés keretében letiltjuk a szkriptfuttatást.
  • Telepítjük a PHP-frissítést, és weboldalanként dokumentáljuk a javítási állapotot.

Gyakori kérdések

Hová menti a PHP elsőként a feltöltött fájlokat?

Egy ideiglenes könyvtárba. Alapértelmezés szerint ez a rendszer ideiglenes könyvtára, amely az upload_tmp_dir-rel módosítható. Ha a szkript nem helyezi át a fájlt, a PHP a kérés végén törli.

Megbízhatok a $_FILES type mezőjében?

Nem. Az MIME-típust a böngésző jelenti, a PHP a kézikönyv szerint nem ellenőrzi. A name és a full_path is a feladótól származik. A tényleges fájltípust a szerveroldalon, a tartalom alapján állapítsa meg.

Miért üres a $_FILES, pedig küldtek fájlt?

Többnyire a teljes kérés nagyobb volt a post_max_size-nál. Ilyenkor a PHP teljesen kiüríti a $_POST-ot és a $_FILES-t, a tömbben hibakód nélkül. További okok: hiányzó enctype az űrlapban vagy kikapcsolt file_uploads.

Segít a PHP2Shell ellen, ha az alkalmazásban megtiltom a feltöltéseket?

Nem. A kéradatok feldolgozása a PHP-ban történik, még az alkalmazáskód futása előtt. A PHP-frissítés és az összes worker újraindítása hatásos; a szűkebb korlátok csak átmeneti intézkedések.

Mi a különbség az upload_max_filesize és a post_max_size között?

Az upload_max_filesize az egyes fájlokat korlátozza, a post_max_size a kérés teljes tartalmát az összes fájllal és mezővel együtt. A post_max_size-nak ezért nagyobbnak kell lennie az upload_max_filesize-nál.

Források

Azonnali kapcsolat

Minden óra számít. Írjon nekünk most.

Ismertesse röviden a rendszert, a PHP-verziót és a megfigyelését. Jelentkezünk, tisztázzuk a helyzetet, és távolról dolgozunk, amíg az incidens le nem zárul és dokumentálva nem lesz.

Azonnali segítség