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 →

Prisijungimo duomenų ir .env failų teisinga apsauga

Kaip PHP projektuose apsaugoti duomenų bazės slaptažodžius, API raktus ir kitas paslaptis: .env failai už žiniatinklio šakninio katalogo, užraktai žiniatinklio serveryje, siauros teisės ir tvarkingas pakeitimas po incidento.

Būsena 5 min. skaitymoSaugus programavimas

Trumpai: .env failą apsaugote, jo apskritai nedėdami viešai pasiekiamame kataloge: žiniatinklio šakninis katalogas rodo į poaplankį kaip public/, o konfigūracija yra vienu lygiu aukščiau. Papildomai žiniatinklio serveris užrakina visus failus su tašku pradžioje, failas skaitomas tik savininko ir PHP proceso ir niekada nepatenka į Git saugyklą. Po įsilaužimo visi jame esantys prisijungimo duomenys laikomi žinomais ir pakeičiami.

Failas su namų raktais

Šiuolaikiniai PHP projektai mielai deda savo paslaptis į failą pavadinimu .env: duomenų bazės slaptažodį, prieigą prie pašto serverio, API raktus mokėjimo ir siuntų paslaugoms, raktą, kuriuo programa pasirašo slapukus. Karkasai kaip Laravel ir Symfony naudoja šį šabloną, daug savų kūrinių jį perėmė.

Idėja gera: konfigūracija ir kodas atskirti, o kiekviena aplinka gauna savas reikšmes. Pavojinga tampa, kai failas atsiduria ne tame kataloge. Jei jis žiniatinklio šakniniame kataloge, o žiniatinklio serveris jo neužrakina, pakanka vieno kreipinio naršyklėje, kad būtų perskaitytos visos prieigos iš karto.

Be to, yra variantų su kitais pavadinimais: .env.local, .env.production, config.local.php ar failai su prisijungimo duomenimis saugojimo paslaugoms. Kas čia aprašyta .env, galioja visiems failams, kuriuose yra paslapčių.

Tokių failų nuolat ieško automatiniai skaneriai. Tai ne atskirų užpuolikų specialybė, o interneto foninis triukšmas, panašus į masinius nepataisytų PHP versijų skenavimus.

Kur turėtų būti .env failas

Veiksmingiausia priemonė yra struktūrinė: žiniatinklio serveris gali pateikti tik tą aplanką, kuris tikrai turi būti viešas. Laravel ir Symfony tai aplankas public/. Viskas kita, t. y. kodas, konfigūracija, žurnalai ir .env, yra aukščiau ir per HTTP apskritai neadresuojama.

/srv/www/shop/
├── .env              ← nepasiekiamas
├── config/
├── src/
├── vendor/
└── public/           ← vienintelis žiniatinklio šakninis katalogas
    ├── index.php
    └── assets/

Praktikoje žiniatinklio šakninis katalogas vis dėlto dažnai rodo į patį projekto katalogą, pavyzdžiui, nes taip nurodo talpinimo valdymo skydelis arba perkeliant nebuvo pritaikytas kelias. Todėl žiniatinklio serverio konfigūracijoje ar skydelyje patikrinkite, kur rodo root arba DocumentRoot.

.env failo apsauga: užraktas žiniatinklio serveryje kaip antra linija

Jei žiniatinklio šakninio katalogo pakeisti negalima arba norite papildomos apsaugos, užrakinkite paslėptus failus žiniatinklio serveryje. Aplankas .well-known turi likti pasiekiamas, nes jis, be kita ko, naudojamas sertifikatams išduoti.

# Užrakinti visus failus ir aplankus su tašku pradžioje, išskyrus .well-known
location ~ /\.(?!well-known/) {
    deny all;
    return 404;
}
# Užrakinti failus su tašku pradžioje
<FilesMatch "^\.">
    Require all denied
</FilesMatch>

Atsakymas 404 vietoj 403 neišduoda, kad failas egzistuoja. Ar užraktas veikia, patikrinkite iš išorės:

# Tikimasi: 403 arba 404, niekada 200
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/.env
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/.env.example
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/.env.bak

Paskutinės dvi eilutės neatsitiktinės: kopijos kaip .env.bak ar .env.old atsiranda atliekant priežiūros darbus ir dažnai pamirštamos. Daugiau apie tokias liekanas rašoma Atsarginių kopijų failai žiniatinklio šakniniame kataloge.

Teisės, Git ir elgesys su kopijomis

Ir už žiniatinklio šakninio katalogo ribų galioja mažiausių teisių principas. Patikrinta struktūra:

  1. Savininkas yra diegimo (deploy) naudotojas, o ne PHP procesas.
  2. Grupė yra PHP-FPM baseino grupė, kuri gali tik skaityti; teisės 640.
  3. Jokio rašymo prieigos PHP procesui. Programa neprivalo galėti keisti savo prisijungimo duomenų.
  4. Jokių tikrų reikšmių saugykloje: įtraukiamas tik .env.example su vietos žymekliais, tikras failas įrašytas į .gitignore.
  5. Atskiros reikšmės kiekvienai aplinkai: kūrimas, parengiamoji aplinka (staging) ir gamyba naudoja skirtingas prieigas, kad nutekėjimas bandomojoje aplinkoje neatvertų gamybos.
chown deploy:shop-php /srv/www/shop/.env
chmod 640 /srv/www/shop/.env
# Patikrinti, ar failas kada nors buvo įtrauktas
git log --all --oneline -- .env

Atkreipkite dėmesį ir į klaidų puslapius. Karkasai derinimo režimu kartais rodo aplinkos kintamuosius ir konfigūracijos reikšmes; gamybos sistemoje šis režimas turi būti išjungtas. Patikrinkite tai po kiekvieno diegimo, nes neteisinga reikšmė pačiame .env gali jį vėl įjungti.

Jei paskutinė komanda pateikia radinių, prisijungimo duomenys yra Git istorijoje ir laikomi atskleistais, net jei failo šiandien nėra. Kodėl tai ypač jautru, kai .git aplankas yra serveryje, aprašo Viešas .git aplankas: nuvertinamas duomenų nutekėjimas. Esminius dalykus apie teises aiškina vadovas Failų teisės žiniatinklio serveryje.

Svarbu

Bandomieji failai su phpinfo() rodo aplinkos kintamuosius. Kas paslaptis perduoda kaip aplinkos kintamuosius, išduoda jas per pamirštą bandomąjį failą. Pagrindai pateikti phpinfo() failai: kodėl jie turi išnykti.

Po įsilaužimo: prisijungimo duomenų pakeitimas

Joks užraktas neapsaugo nuo užpuoliko, kuris jau vykdo kodą serveryje. PHP procesas turi galėti skaityti savo konfigūraciją, taigi ir įterptas kodas tame pačiame procese tai gali. Po PHP2Shell todėl galioja: jei įsilaužimo atmesti negalima, visi serveryje esantys prisijungimo duomenys traktuojami kaip žinomi.

Tvarkingas pakeitimas apima duomenų bazės slaptažodžius, pašto ir SMTP prieigas, išorinių paslaugų API raktus, programos parašo raktus ir prieigas prie saugojimo paslaugų. Eiliškumas ir laikas turi būti suplanuoti: kas pirmiausia pakeičia, o paskui sutvarko serverį, galbūt iš karto atiduoda užpuolikui ir naujas reikšmes.

Nutekėjimo žalą apribojate dar iš anksto, kai kiekviena paslaptis gali tik tiek, kiek būtina. Svetainės duomenų bazės naudotojui nereikia teisių į kitas duomenų bazes. Išorinių paslaugų API raktus daugelis teikėjų leidžia apriboti atskiromis funkcijomis ar siuntėjo adresais, pavyzdžiui, kurti siuntas, bet neinicijuoti išmokų. Ir kiekviena programa gauna savas prieigas, užuot kelioms svetainėms dalijantis tuo pačiu pašto paskyra ar raktu. Tada nutekėjimas liečia aiškiai apibrėžtą sritį, o pakeitimas lieka apžvelgiamas.

Konteinerių aplinkose .env failo nėra nei atvaizde (image), nei viešai pasiekiamame registre. Išskirkite jį per .dockerignore ir paslaptis perduokite tik vykdymo metu platformos mechanizmais.

Ilgalaikėje perspektyvoje verta pažvelgti į centrines paslapčių saugyklas, kaip rekomenduoja OWASP: paslaptys vienoje vietoje, su prieigos žurnalu, reguliariu keitimu ir kuo trumpesniu galiojimu.

Kaip PHP SOS padeda konkrečiai?

  • Iš išorės tikriname, ar jūsų svetainių konfigūracijos failai, kopijos ir paslėpti failai pasiekiami.
  • Žiniatinklio šakninį katalogą, žiniatinklio serverio užraktus ir failų teises perkeliame taip, kad paslaptys per HTTP nebebūtų pasiekiamos.
  • Tikriname saugyklas ir diegimus dėl įtrauktų prisijungimo duomenų.
  • Po incidento planuojame ir lydime visų paveiktų prieigų pakeitimą teisinga tvarka.

Šie darbai yra mūsų PHP žiniatinklio serverių sutvirtinimo dalis.

Dažni klausimai

Ar .env failas žiniatinklio šakniniame kataloge automatiškai viešas?

Ne automatiškai, bet dažnai. Ar jį galima atsisiųsti, priklauso nuo žiniatinklio serverio konfigūracijos. Daugelis numatytųjų konfigūracijų saugo tik .htaccess failus, o ne kitus failus su tašku pradžioje. Bandymas su curl išaiškina.

Ar aplinkos kintamieji saugesni už .env failą?

Ne iš principo. OWASP pažymi, kad aplinkos kintamuosius gali skaityti visi naudotojo procesai ir jie gali atsirasti žurnaluose ar atminties išklotinėse. Tačiau jie leidžia išvengti failo žiniatinklio šakniniame kataloge. Geriau centrinės paslapčių saugyklos, kur aplinka jas palaiko.

Ką daryti, jei .env failas buvo pasiekiamas?

Visus jame esančius prisijungimo duomenis laikykite žinomais ir pakeiskite: duomenų bazę, paštą, API, mokėjimo paslaugas, programos raktus. Po to prieigos žurnaluose patikrinkite, ar failas buvo kviečiamas, o jei yra asmens duomenų, įtraukite duomenų apsaugos pareigūną.

Ar .env failas turi būti Git saugykloje?

Ne. Į saugyklą daugiausia gali patekti šablonas be tikrų reikšmių, pavyzdžiui, .env.example. Tikras failas išskiriamas per .gitignore ir serveryje pateikiamas atskirai.

Ar phpinfo() gali išduoti prisijungimo duomenis?

Taip. phpinfo() rodo, be kita ko, aplinkos kintamuosius ir serverio kintamuosius. Jei ten yra paslapčių, jos išvedamos kartu. Todėl bandomųjų failų su phpinfo() niekada neturi būti pasiekiamoje sistemoje.

Š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