Dabartinė padėtis: PHP2Shell. Du kritiniai PHP pažeidžiamumai (CVSS 9,2) leidžia vykdyti kenkėjišką kodą be prisijungimo. Pataisos nuo 2026-10-21.Ką dabar daryti →

Superglobalūs kintamieji: $_GET, $_POST, $_FILES ir kiti

Superglobalūs kintamieji yra masyvai, per kuriuos PHP kodas gauna užklausos duomenis. Kas žino, kaip PHP juos užpildo ir kokios ribos galioja, rašo saugesnį kodą ir geriau supranta PHP2Shell.

Būsena 4 min. skaitymoPHP žinios

Trumpai: superglobalūs kintamieji yra iš anksto apibrėžti masyvai, kuriuos PHP automatiškai užpildo per kiekvieną užklausą ir kurie pasiekiami visame kode. $_GET turi adreso parametrus, $_POST formų duomenis, $_FILES įkeltus failus, $_COOKIE slapukus, o $_SERVER duomenis apie užklausą ir serverį. PHP šiuos masyvus sukuria prieš pradedant vykdyti jūsų programos kodą. Todėl spragų būtent šiame apdorojime, kaip esant PHP2Shell, programos patikros sustabdyti negali.

Kas yra superglobalūs kintamieji?

PHP kintamasis paprastai galioja tik funkcijoje, kurioje buvo sukurtas. Superglobalūs kintamieji yra išimtis: jie pasiekiami kiekvienoje galiojimo srityje, jų nereikia pasiimti su global. PHP vadovas nurodo devynis.

Ne technikams galima paaiškinti taip: superglobalūs kintamieji yra programos pašto dėžutė. Viskas, ką lankytojas atsiunčia, ten patenka, kol programa to dar neperskaitė. O viskas pašto dėžutėje potencialiai ateina iš svetimo žmogaus.

Superglobalių kintamųjų apžvalga

Superglobalus kintamasis Turinys Kilmė
$_GET adreso parametrai (query string) klientas
$_POST POST užklausos formos laukai klientas
$_FILES duomenys apie įkeltus failus klientas, PHP paruošta
$_COOKIE naršyklės kartu siunčiami slapukai klientas
$_REQUEST GET, POST ir prireikus slapukų mišinys klientas
$_SERVER užklausos antraštės, metodas, keliai, serverio duomenys žiniatinklio serveris ir klientas kartu
$_ENV aplinkos kintamieji serveris
$_SESSION dabartinės sesijos duomenys serverio saugykla
$GLOBALS visi globalieji kintamieji skriptas

Ypač klastingas yra $_SERVER. Pasak vadovo, kiekvienai užklausos antraštei PHP sukuria įrašą su HTTP_ pradžioje, pavyzdžiui, HTTP_USER_AGENT. Šias reikšmes nustato pats klientas. Ir SERVER_NAME, pasak vadovo, gali turėti kliento pateiktą kompiuterio vardą ir saugumo sprendimams nėra patikimas.

Kaip PHP užpildo superglobalius kintamuosius

Dar prieš įvykdant pirmąjį jūsų skripto simbolį PHP jau yra dirbęs. Jis nuskaito adresą, antraštes ir užklausos turinį, išskaido juos ir rezultatus deda į masyvus. Šį žingsnį valdo keli nustatymai:

  1. variables_order (numatytoji EGPCS) nustato, kurie superglobalūs kintamieji apskritai sukuriami: Environment, GET, POST, Cookie, Server.
  2. request_order (numatytoji tuščia) nustato, iš ko sudaromas $_REQUEST. Jei tuščia, galioja variables_order. Pasak vadovo, kartu pateikiami php.ini failai slapukus saugumo sumetimais praleidžia.
  3. max_input_vars (numatytoji 1000) ir max_input_nesting_level (numatytoji 64) riboja įvesties kintamųjų skaičių ir įdėtumą.
  4. post_max_size (numatytoji 8M) riboja užklausos turinį. Jei užklausa didesnė, $_POST ir $_FILES lieka tušti.
  5. enable_post_data_reading (numatytoji įjungta) valdo, ar PHP POST užklausų turinį apskritai apdoroja automatiškai.

Jei enable_post_data_reading išjungtas, programa neapdorotą turinį skaito pati per php://input. Nuo PHP 8.4.0 papildomai yra request_parse_body(), kuri formų ir įkėlimų duomenis apdoroja ir kitiems metodams nei POST bei leidžia nustatyti savas ribas. Kaip smulkiai vyksta įkėlimo dalis, paaiškina puslapis Kaip PHP apdoroja failų įkėlimus.

Saugus elgesys su užklausos duomenimis

Principas paprastas: kiekviena reikšmė iš $_GET, $_POST, $_COOKIE, $_FILES ir $_SERVER įrašų HTTP_ yra svetima įvestis. Ji tikrinama priimant ir tinkamai užmaskuojama išvedant.

<?php
declare(strict_types=1);

// Tikimasi sveikojo skaičiaus: patikrinti, o ne aklai konvertuoti
$seite = filter_var($_GET['seite'] ?? '1', FILTER_VALIDATE_INT, [
    'options' => ['min_range' => 1, 'max_range' => 500],
]);
if ($seite === false) {
    http_response_code(400);
    exit('Ungültige Seitenzahl');
}

// Leisti tik leidžiamas reikšmes
$sortierung = in_array($_GET['sort'] ?? '', ['name', 'datum'], true)
    ? $_GET['sort']
    : 'datum';

// Išvestį visada užmaskuoti
echo htmlspecialchars($_POST['kommentar'] ?? '', ENT_QUOTES, 'UTF-8');

Dažna kliūtis yra duomenys apie užklausos kilmę. Jei prieš žiniatinklio serverį stovi atvirkštinis tarpinis serveris (reverse proxy), apkrovos paskirstytojas (load balancer) ar CDN, $_SERVER['REMOTE_ADDR'] turi šio tarpininko, o ne lankytojo adresą. Tikrasis adresas tuomet yra antraštėje, pavyzdžiui, X-Forwarded-For, kurią tačiau gali nustatyti kiekvienas klientas. Programa tokias antraštes gali vertinti tik tada, kai užklausa įrodomai ateina iš savo, žinomo tarpinio serverio. Kitaip blokavimus pagal IP adresą ar žurnalus galima lengvai apgauti. Panašiai ir su HTTPS: jei šifravimas baigiasi tarpiniame serveryje, programa turi aiškiai žinoti, kad pradinis ryšys buvo šifruotas.

Daugiau patvirtinimo ir filtravimo šablonų pateikia straipsnis Įvesties tikrinimas ir filtravimas PHP. Sesijos duomenims $_SESSION galioja savos taisyklės; jos aprašytos puslapyje Sesijos ir slapukai PHP.

Superglobalūs kintamieji ir PHP2Shell: kas vyksta prieš jūsų kodą

Čia glūdi ryšys su dabartine padėtimi. CVE-2026-109618 aprašo, kad atminties trūkumo būsena gali pertraukti PHP, kai užklausos duomenys inicializuoti tik iš dalies; užklausą sutvarkant neteisingi duomenys tuomet gali būti laikomi teisingais. Esant CVE-2026-109619, vidinė užklausos būsena gali išlikti atlaisvinus atmintį ir būti panaudota vėlesnės užklausos tame pačiame darbiniame procese (worker).

Taigi abi spragos yra apdorojime, kurį PHP pats atlieka aplink užklausą, o ne programos kode. PHP komanda didžiausią riziką priskiria mod_php; ten parodytas exploit dar prieš pradedant vykdyti programos kodą. Joks filter_var() ir jokia programos patikra to negali užkirsti.

Veikti nedelsiant

Privaloma atnaujinti iki PHP 8.5.12, 8.4.27, 8.3.36 ar 8.2.35 ir iš naujo paleisti visus PHP procesus. php.net pereinamosios priemonės, pavyzdžiui, siauresnės post_max_size ribos, nėra visiška apsauga.

Kaip PHP SOS padeda konkrečiai?

  • Tikriname veiksmingas užklausos duomenų ribas kiekvienai svetainei ir nustatome jas pagal programą.
  • Įdiegiame PHP atnaujinimą, iš naujo paleidžiame visus darbinius procesus ir pataisų būseną įrodome savo PHP pataisų paslaugos rėmuose.
  • Individualius sprendimus tikriname, ar reikšmės iš superglobalių kintamųjų nepatikrintos nepatenka į duomenų bazę, failų sistemą ar išvestį.
  • Saugome žiniatinklio serverio žurnalus nuo 2026-10-20, kad vėlesnė analizė išliktų įmanoma.

Dažni klausimai

Kiek superglobalių kintamųjų yra PHP?

PHP vadovas nurodo devynis: $GLOBALS, $_SERVER, $_GET, $_POST, $_FILES, $_COOKIE, $_SESSION, $_REQUEST ir $_ENV. Jie pasiekiami kiekvienoje galiojimo srityje, taip pat funkcijose ir metoduose.

Ar $_SERVER reikšmėmis galima pasitikėti?

Tik iš dalies. Įrašai, prasidedantys HTTP_, ateina iš kliento užklausos antraščių. Vadovas, pavyzdžiui, įspėja, kad SERVER_NAME gali atspindėti kliento pateiktą kompiuterio vardą ir saugumo sprendimams nėra patikimas.

Kodėl $_POST kartais tuščias, nors forma išsiųsta?

Dažniausia priežastis yra užklausa, didesnė už post_max_size. Tuomet, pasak vadovo, $_POST ir $_FILES lieka tušti. Taip pat tai sukelia išjungtas nustatymas enable_post_data_reading.

Ar reikėtų naudoti $_REQUEST?

Geriau ne. $_REQUEST sumaišo duomenis iš skirtingų šaltinių, o kuris šaltinis nugali, priklauso nuo request_order ir variables_order. Reikšmes skaitykite tikslingai iš $_GET arba $_POST.

Šaltiniai

Skubus kontaktas

Kiekviena valanda svarbi. Parašykite mums dabar.

Trumpai aprašykite sistemą, PHP versiją ir pastebėjimus. Mes atsakysime, išsiaiškinsime padėtį ir dirbsime nuotoliu, kol incidentas bus užbaigtas ir dokumentuotas.

Skubi pagalba