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 →

Statinė analizė: PHPStan ir Psalm

PHPStan ir Psalm randa PHP kodo klaidas jo nevykdydami. Psalm papildomai seka nesaugius duomenų srautus. Spragų paties PHP interpretatoriuje nė vienas jų neranda.

Būsena 4 min. skaitymoPHP žinios

Trumpai: Statinė analizė tikrina PHP kodą jo nevykdydama ir taip randa tipų klaidas, neapibrėžtus kintamuosius, negyvą kodą ir iškvietimus galimai tuščioms reikšmėms. Du plačiai naudojami įrankiai yra PHPStan (taisyklių lygiai nuo 0 iki 10) ir Psalm (klaidų lygiai nuo 1 iki 8, be to, taint analizė nesaugiems duomenų srautams). Jie randa klaidas jūsų programoje, o ne PHP interpretatoriuje; nuo spragų, tokių kaip PHP2Shell, padeda tik PHP atnaujinimas.

Kas yra statinė analizė?

Testas vykdo kodą ir lygina rezultatą. Statinė analizė, priešingai, skaito kodą kaip labai kruopštus tikrintojas ir iš tipų, grąžinamų reikšmių bei iškvietimų daro išvadą, kur kas nors gali nepavykti. Ji randa klaidas ir tose šakose, kurių nė vienas testas niekada nepasiekia.

Sprendimų priėmėjams nauda paprasta: klaidos, rastos prieš paleidžiant, kainuoja trupmeną to, ką kainuoja klaidos, kurias pastebi klientai. Kūrėjams tai nuolatinis palydovas, veikiantis kūrimo aplinkoje ir CI grandinėje. Jei analizė pakeitimui pasipriešina, jis nepriimamas, kol klaida neištaisoma. Taip neauga naujas palikimas, o esamas palaipsniui mažinamas. Kartu su testais su PHPUnit ir Pest ji sudaro kodo kokybės pagrindą.

PHPStan: taisyklių lygiai nuo 0 iki 10

PHPStan diegiamas kaip kūrimo priklausomybė, o veikti jai reikia PHP nuo 7.4:

composer require --dev phpstan/phpstan
vendor/bin/phpstan analyse src tests

Be papildomų nurodymų PHPStan tikrina tik būtiniausia. Griežtumą valdote per vienuolika lygių, kiekvienas apima žemesnius:

Lygis Kas papildomai tikrinama (pasirinkimas)
0 nežinomos klasės ir funkcijos, neteisingas argumentų skaičius, visada neapibrėžti kintamieji
3 grąžinamų reikšmių tipai ir tipai, priskiriami savybėms
5 argumentų tipai funkcijų ir metodų iškvietimuose
6 trūkstami tipų nurodymai
8 metodų iškvietimai ir savybių pasiekimai reikšmėms, kurios gali būti null
10 griežčiausias elgesys su mixed, taip pat esant trūkstamiems tipams

Su --level max visada vykdomas aukščiausias lygis. Dokumentacija tačiau perspėja, kad PHPStan atnaujinimas tuomet gali atnešti daug naujų pranešimų. Tipinis radinys nuo 8 lygio:

<?php
function kundenname(?Kunde $kunde): string
{
    return $kunde->name();   // PHPStan: iškvietimas reikšmei, kuri gali būti null
}

PHPStan įdiegimas be klaidų potvynio: baseline

Išaugusiuose projektuose PHPStan aukštu lygiu dažnai praneša apie šimtus vietų. Baseline išsprendžia problemą: ji visus esamus pranešimus išsaugo faile, ir nuo tada PHPStan praneša tik apie naujas klaidas.

vendor/bin/phpstan analyse --level 6 src tests --generate-baseline

Sukurtą failą phpstan-baseline.neon įtraukiate į konfigūraciją:

includes:
    - phpstan-baseline.neon

parameters:
    level: 6
    paths:
        - src
        - tests

Taip senasis palikimas lieka matomai dokumentuotas, o naujas kodas nuo pat pradžių turi būti švarus.

Psalm ir taint analizė

Psalm siekia panašių tikslų kaip PHPStan. Lygiai eina atvirkščiai: 1 yra griežčiausias, 8 švelniausias, numatytasis yra 2. Psalm reikia PHP nuo 8.2, o paruošiamas jis taip:

composer require --dev vimeo/psalm
./vendor/bin/psalm --init
./vendor/bin/psalm --taint-analysis

Taint analizė saugumui ypač įdomi. „Taint“ reiškia suteršimą: Psalm pažymi duomenis iš šaltinių, kuriuos gali valdyti užpuolikas, pavyzdžiui, $_GET, $_POST, $_COOKIE, $_REQUEST ar php://input. Tada seka, ar šie duomenys nesaugomi pasiekia pavojingas vietas, vadinamąsias nutekėjimo vietas (sinks): išvestį su echo, include, header ar SQL užklausas. Prie įmontuotų kategorijų, be kita ko, priklauso sql, html, shell, include, eval, ssrf ir unserialize.

<?php
// Psalm praneša apie srautą iš $_GET į HTML išvestį (kategorija html)
echo 'Hallo ' . $_GET['name'];

// Ištaisyta: išvestį maskuoti pagal kontekstą
echo 'Hallo ' . htmlspecialchars($_GET['name'] ?? '', ENT_QUOTES, 'UTF-8');

Psalm dokumentacija atvirai nurodo ribas: analizė daro prielaidą, kad maskavimas atliktas teisingai. Smulkios klaidos, pavyzdžiui, trūkstamos kabutės aplink HTML atributą, vis tiek gali palikti spragų. Todėl Psalm rekomenduoja parametrizuotas užklausas SQL ir kontekstą suvokiančius šablonus HTML. Rezultatus galima išvesti SARIF formatu, kurį, be kita ko, supranta GitHub Code Scanning.

Statinė analizė ir saugumas po PHP2Shell

Čia verta sąžiningai atriboti. PHP2Shell, t. y. CVE-2026-109618 ir CVE-2026-109619, slypi PHP interpretatoriuje. Joks įrankis, skaitantis jūsų programos kodą, šių spragų neranda, ir joks kodo pakeitimas jų neuždaro. Tai pasiekia tik atnaujinimas iki PHP 8.5.12, 8.4.27, 8.3.36 ar 8.2.35.

Vis dėlto statinė analizė saugumui prisideda trimis atžvilgiais:

  1. Atnaujinamumas: randa kodą, kuris naujose PHP versijose nebeveikia. Taip sumažėja kliūtis pereiti nuo 8.1 ar 8.2 prie palaikomos versijos.
  2. Savos spragos: taint analizė randa kelius SQL injekcijai, kryžminiam svetainių skriptų vykdymui (XSS) ar failų įtraukimui. PHP projektas savo saugumo politikoje aiškiai nurodo, kad nepatikrintos įvestys funkcijoms, tokioms kaip mysqli_query(), nėra PHP klaida, o priklauso programos atsakomybei.
  3. Patikimumas: daug mirtinų klaidų atsiranda dėl iškvietimų null reikšmėms ar neteisingų tipų. Dėl CVE-2026-109619 php.net aiškiai pataria programoje ištaisyti iš išorės sukeliamas mirtinas klaidas.

Statinė analizė neatstoja žmogaus atlikto saugumo kodo peržiūros, bet daro ją efektyvesnę, nes įprastos klaidos iš anksto išfiltruotos.

Kaip PHP SOS padeda konkrečiai?

Pagal saugumo auditą ir skverbties testą veikiame taip:

  • Įrengti įrankius: PHPStan ar Psalm su tinkamu lygiu ir baseline, įtrauktus į jūsų esamą grandinę.
  • Įvertinti saugumo radinius: tikriname taint analizės rezultatus ir atskiriame tikras rizikas nuo klaidingų aliarmų.
  • Paruošti atnaujinimą: parodome, kurios vietos blokuoja perėjimą prie palaikomos PHP versijos.
  • Perduoti rezultatus: gaunate prioritetizuotą sąrašą su konkrečiomis kodo vietomis jūsų komandai ar agentūrai.

Dažni klausimai

Kuo skiriasi PHPStan ir Psalm?

Abu tikrina tipus ir randa klaidas nevykdydami kodo. PHPStan savo lygius skaičiuoja nuo 0 (švelnus) iki 10 (griežtas), Psalm nuo 8 (švelnus) iki 1 (griežtas). Psalm turi įmontuotą taint analizę saugumo problemoms.

Ar PHPStan galiu įdiegti senam projektui?

Taip. Su baseline PHPStan visus esamus pranešimus išsaugo faile ir po to praneša tik apie naujas klaidas. Taip komanda pradeda be klaidų potvynio ir palaipsniui mažina senąjį palikimą.

Ar statinė analizė suranda PHP2Shell?

Ne. PHP2Shell slypi PHP interpretatoriuje, o ne jūsų kode. Padeda tik PHP atnaujinimas. Tačiau statinė analizė padeda paruošti kodą naujoms PHP versijoms, kad atnaujinti būtų galima greičiau.

Kokį lygį pasirinkti?

Pradžiai žemą lygį be baseline arba aukštesnį lygį su baseline. Svarbiau už skaičių yra tai, kad analizė automatiškai vykdoma su kiekvienu pakeitimu ir nepraleidžia naujų klaidų.

Š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