# Saugumo kodo peržiūra PHP projektams

> Saugumo kodo peržiūra PHP: bazinė ar pakeitimų peržiūra, rizikingos funkcijos, įrankiai kaip PHPStan ir Psalm ir kontrolinis sąrašas savo komandai.

Šaltinis: https://phpsos.de/lt/blog/sicherheits-code-review-php/  
Būsena: 2026-10-25  
Teikėjas: PHP SOS, PHP avarinė pagalba ir serverio sauga. Skubi pagalba per „WhatsApp“: https://wa.me/491736494914?text=Sveiki%2C%20PHP%20SOS%2C%20mums%20reikia%20pagalbos%20su%20m%C5%ABs%C5%B3%20PHP%20serveriu.%20%C4%AEmon%C4%97%3A%20%E2%80%A6%20Svetain%C4%97%3A%20%E2%80%A6

**Trumpai:** saugumo kodo peržiūra PHP yra tikslingas šaltinio teksto skaitymas su vienu klausimu: kur svetima įvestis gali padaryti tai, ko neturėtų? Pasiteisina dvi formos: kiekvieno pakeitimo peržiūra ir viso projekto bazinė peržiūra, paremta statine analize su PHPStan ar Psalm. PHP interpretatoriaus spragų kaip PHP2Shell peržiūra neras, bet suras daugybę klaidų, atsirandančių savame kode.

## Kodėl būtent dabar pažvelgti į savo kodą?

PHP2Shell paskutinę 2026 m. spalio savaitę pirmiausia užėmė administratorius. Pataisyti, paleisti iš naujo, įrodyti: darbas gulė ant serverio. Kūrimo komandoms po to lieka nepatogus klausimas. Jei užpuolikas per kitą spragą gali vykdyti kodą, ką jis randa mūsų programoje? Ir kiek šių spragų parašėme patys?

OWASP Top 10 jau daug metų rodo, kad dauguma žiniatinklio programų silpnybių nėra egzotinės. Aukštai stovi trūkstama prieigos kontrolė, injekcija ir nesaugi konfigūracija. Tai klaidos, kurias įgudusi akis randa šaltinio tekste ilgai prieš tai, kai užpuolikas jas išbando.

Be to, yra praktinė priežastis. Daug įmonių dabar vis tiek tikrina, pataiso ir sutvirtina savo serverius. Kas tuo pat metu apžiūri ir savo programą, uždaro tarpą tarp eksploatavimo ir kūrimo. Sutvirtintas serveris su pažeidžiama programa lieka atakuojamas, o tvarkingai parašyta programa su nepataisytu PHP taip pat.

## Bazinė ar pakeitimų peržiūra?

OWASP Cheat Sheet apie Secure Code Review skiria dvi rūšis, kurios praktikoje papildo viena kitą:

| Rūšis | Kada | Apimtis | Tikslas |
|---|---|---|---|
| Bazinė peržiūra (Baseline) | naujas projektas, didelis leidimas, po incidento | visas projektas, pasvertas pagal riziką | surinkti silpnybių inventorių |
| Pakeitimų peržiūra (Diff) | kiekvienas Pull Request | tik pakeistas kodas | užkirsti kelią naujoms klaidoms |

Bazinė peržiūra po incidento ypač vertinga. Kas ką tik išvalė serverį, turėtų žinoti, ar programa siūlo kitų įsiskverbimo kelių. Pakeitimų peržiūra po to išlaiko būseną tvarkingą, nes kiekvienas pakeitimas prieš sujungimą skaitomas ir saugumo požiūriu.

## Kodo peržiūra PHP: kur kaupiasi saugumo klaidos

PHP projektuose verta tikslingai pažvelgti į tam tikras funkcijas ir šablonus. Jie nėra draudžiami, bet kiekvienas radinys nusipelno klausimo, ar į juos gali patekti svetimi duomenys.

| Kodo šablonas | Galima rizika | Pagilinimas |
|---|---|---|
| SQL per eilučių sujungimą su kintamaisiais | SQL injekcija | [SQL injekcijos PHP prevencija](https://phpsos.de/lt/ratgeber/sql-injection-php/) |
| `unserialize()` su duomenimis iš išorės | objekto injekcija | [Nesaugi deserializacija PHP](https://phpsos.de/lt/ratgeber/deserialisierung-php/) |
| `include` ar `require` su kintamu keliu | svetimų failų įtraukimas | [Local ir Remote File Inclusion prevencija](https://phpsos.de/lt/ratgeber/lfi-rfi/) |
| `exec()`, `system()`, `shell_exec()`, `proc_open()` | komandų vykdymas | Command Injection |
| Išvestis be `htmlspecialchars()` | Cross-Site Scripting | kontekstui tinkamas ekranavimas (escaping) |
| `==` su žetonais ar maišomis (hash) | tipų pavertimas apeina patikras | `hash_equals()`, griežti palyginimai |
| `eval()`, `extract()` su įvestimis | kodo ar kintamųjų injekcija | dažniausiai išbraukti be pakaitalo |

Greitą pirmą apžvalgą duoda paprasta paieška. Ji peržiūros nepakeičia, bet parodo, nuo ko pradėti:

```bash
# Rizikingų funkcijų radiniai savame kode (vendor išskirtas)
grep -rnE "\b(unserialize|eval|extract|shell_exec|exec|system|passthru|proc_open)\s*\(" src/ app/ 2>/dev/null
```

Bent jau tiek pat svarbu, ko kode trūksta. Ar kiekvienas valdiklis (controller) tikrina, ar prisijungęs naudotojas gali matyti ar keisti būtent šį duomenų įrašą? Ar įkėlimai apribojami pagal tipą ir vietą? Tokių spragų neranda joks funkcijų pavadinimų paieškos įrankis, tik eigos skaitymas.

## Įrankiai, laikantys peržiūrą

Statinė analizė tikrina kodą jo nevykdydama. PHPStan ir Psalm randa tipų klaidas, nepasiekiamą kodą ir neteisingas prielaidas apie grąžinamas reikšmes. Psalm papildomai siūlo taint analizę, kuri seka, ar duomenys iš užklausų netikrinti teka į kritines vietas. Abu galima griežtinti pakopomis, todėl įsijungti gali ir senesni projektai. Apžvalgą pateikia [Statinė analizė: PHPStan ir Psalm](https://phpsos.de/lt/php/statische-analyse/).

```bash
# Statinė analizė projekte, lygį didinti palaipsniui
vendor/bin/phpstan analyse src --level=5
# Taint analizė su Psalm
vendor/bin/psalm --taint-analysis
```

Įrankiai pateikia užuominas, o ne nuosprendžius. Kiekvienam radiniui reikia įvertinimo, o tuščia ataskaita nereiškia, kad programa saugi.

Tiek pat svarbu kaip radimas yra užfiksavimas. Kiekvienas radinys turėtų būti užfiksuotas su radimo vieta, trumpu aprašymu, rizikos įvertinimu, rekomenduojamu ištaisymu ir būsena, geriausia tiesiai komandos užduočių sistemoje. Taip galima atsekti, kas ištaisyta, kas sąmoningai priimta ir kas dar atvira. Po ištaisymo verta antra žvilgsnis: ar pašalinta priežastis, ar tik vienas simptomas? Ar tas pats šablonas pasirodo kitose kodo vietose? Klaida, kuri kartą padaryta, patirtis rodo, retai slypi tik vienoje vietoje.

## Kontrolinis sąrašas savo komandai

Pakeitimų peržiūroms pasiteisino trumpas, fiksuotas sąrašas. Jis priklauso Pull Request šablonui:

1. Iš kur ateina visi duomenys, kuriuos apdoroja šis pakeitimas, ir ar jie tikrinami serverio pusėje?
2. Ar duomenų bazės užklausos sudaromos tik su vietos žymekliais?
3. Ar kiekviena išvestis ekranuota savo kontekstui, t. y. HTML, atributui, JavaScript ar URL?
4. Ar kodas tikrina teisę būtent šiam objektui, o ne tik prisijungimą?
5. Ar slaptažodžiai, žetonai ar asmens duomenys patenka į žurnalus ar klaidų pranešimus?
6. Ar paslaptys yra kode ar versijuojamuose failuose?
7. Ar įtrauktos naujos priklausomybės ir ar jos prižiūrimos?

> **Patarimas:**
> Saugumui kritines dalis, tokias kaip prisijungimas, teisių valdymas, mokėjimo eigos ir įkėlimai, visada leiskite perskaityti antram asmeniui, kuris kodo nekūrė. Svetima akis randa prielaidas, kurias autorius laiko savaime suprantamomis.

## Kaip PHP SOS padeda konkrečiai?

- Su specializuotais partneriais atliekame jūsų PHP programos bazinę peržiūrą, pasvertą pagal dalis su didžiausia rizika.
- Sukonfigūruojame PHPStan ar Psalm pagal jūsų projekto būklę ir parašome kontrolinį sąrašą jūsų Pull Request.
- Peržiūrą siejame su žvilgsniu į serverį ir konfigūraciją, nes daug spragų atsiranda tik sąveikoje.
- Kur pageidaujama patikra iš išorės, peržiūrą papildome [saugumo auditu ir įsiskverbimo testu](https://phpsos.de/lt/leistungen/sicherheitsaudit-penetrationstest/).

**Išvada:** kodo peržiūra yra pigiausia vieta ištaisyti saugumo klaidas, būtent prieš jas pateikiant. Kas kiekvieną pakeitimą tikrina trumpu sąrašu ir kartkartėmis pilnai peržiūri projektą, nuolat sumažina atakos paviršių.


## Dažni klausimai

**Kuo skiriasi kodo peržiūra nuo įsiskverbimo testo?**  
Kodo peržiūra skaito šaltinio tekstą ir randa klaidas dar prieš jas pateikiant. Įsiskverbimo testas atakuoja veikiančią programą iš išorės. Abu papildo vienas kitą: peržiūra randa priežastis, testas parodo, kas iš tikrųjų išnaudojama.

**Ar kodo peržiūra randa tokias spragas kaip PHP2Shell?**  
Ne. PHP2Shell slypi PHP interpretatoriuje, o ne programos kode. Nuo to padeda tik PHP atnaujinimas su paleidimu iš naujo. Peržiūra randa savo kodo klaidas, pavyzdžiui, injekciją, trūkstamas teisių patikras ar nesaugią deserializaciją.

**Ar PHPStan arba Psalm pakanka saugumo peržiūrai?**  
Jie yra geras pagrindas ir randa daug klaidų automatiškai. Tačiau logikos klaidas, trūkstamas teisių patikras ir neteisingas prielaidas apie eigas atpažįsta tik žmogus, žinantis, ką programa turi daryti.

**Kiek trunka saugumo kodo peržiūra?**  
Tai priklauso nuo apimties. Kiekvieno pakeitimo peržiūra Pull Request užima mažai laiko. Pilna išaugusio projekto peržiūra yra atskiras projektas, kurį pagal riziką apribojama svarbiausiomis dalimis.

## Šaltiniai

- [OWASP: Secure Code Review Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Secure_Code_Review_Cheat_Sheet.html)
- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
- [PHPStan](https://phpstan.org/)
