Īsi sakot: .env failu aizsargājat, vispār neglabājot to publiski sasniedzamā direktorijā: tīmekļa sakne norāda uz apakšmapi, piemēram, public/, konfigurācija atrodas vienu līmeni augstāk. Papildus tīmekļa serveris bloķē visus failus, kuru nosaukums sākas ar punktu, fails ir lasāms tikai īpašniekam un PHP procesam un nekad nepieder Git repozitorijam. Pēc ielaušanās visi tajā esošie piekļuves dati tiek uzskatīti par zināmiem un nomainīti.
Fails ar mājas atslēgām
Moderni PHP projekti savus noslēpumus labprāt glabā failā ar nosaukumu .env: datubāzes parole, piekļuve pasta serverim, API atslēgas maksājumu un piegādes pakalpojumiem, atslēga, ar kuru lietojumprogramma paraksta sīkdatnes. Ietvari, piemēram, Laravel un Symfony, izmanto šo paraugu, daudzi pašizstrādājumi to ir pārņēmuši.
Ideja ir laba: konfigurācija un kods ir nodalīti, un katra vide saņem savas vērtības. Bīstami kļūst, ja fails nonāk nepareizā direktorijā. Ja tas atrodas tīmekļa saknē un tīmekļa serveris to nebloķē, pietiek ar vienu izsaukumu pārlūkā, lai uzreiz nolasītu visas piekļuves.
Klāt nāk varianti ar citiem nosaukumiem: .env.local, .env.production, config.local.php vai faili ar piekļuves datiem glabāšanas pakalpojumiem. Kas šeit aprakstīts par .env, attiecas uz visiem failiem, kuros ir noslēpumi.
Šādus failus nepārtraukti meklē automatizēti skeneri. Tā nav atsevišķu uzbrucēju specialitāte, bet interneta fona troksnis, līdzīgi kā masveida skenēšana pēc neielāpotām PHP versijām.
Kur .env failam jāatrodas
Efektīvākais pasākums ir strukturāls: tīmekļa serverim jāpiegādā tikai tā mape, kurai tiešām jābūt publiskai. Laravel un Symfony tā ir mape public/. Viss pārējais, tātad kods, konfigurācija, žurnāli un .env, atrodas virs tās un pa HTTP vispār nav adresējams.
/srv/www/shop/
├── .env ← nav sasniedzams
├── config/
├── src/
├── vendor/
└── public/ ← vienīgā tīmekļa sakne
├── index.php
└── assets/
Praksē tīmekļa sakne tomēr bieži norāda uz pašu projekta direktoriju, piemēram, tāpēc, ka hostinga panelis to tā nosaka vai pārcelšanās laikā ceļš nav pielāgots. Tāpēc tīmekļa servera konfigurācijā vai panelī pārbaudiet, uz ko norāda root resp. DocumentRoot.
.env faila aizsardzība: bloķēšana tīmekļa serverī kā otrā līnija
Ja tīmekļa sakni nevar mainīt vai vēlaties papildu drošību, bloķējiet slēptos failus tīmekļa serverī. Mapei .well-known pie tam jāpaliek sasniedzamai, jo to cita starpā izmanto sertifikātu izsniegšanai.
# Bloķēt visus failus un mapes, kuru nosaukums sākas ar punktu, izņemot .well-known
location ~ /\.(?!well-known/) {
deny all;
return 404;
}
# Bloķēt failus, kuru nosaukums sākas ar punktu
<FilesMatch "^\.">
Require all denied
</FilesMatch>
Atbilde ar 404, nevis 403, neizpauž, ka fails pastāv. Vai bloķēšana darbojas, pārbaudiet no ārpuses:
# Sagaidāms: 403 vai 404, nekad ne 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
Pēdējās divas rindas nav nejaušība: kopijas, piemēram, .env.bak vai .env.old, rodas apkopes darbu laikā un bieži tiek aizmirstas. Vairāk par šādām atliekām rakstā Rezerves kopiju faili tīmekļa saknē.
Tiesības, Git un darbs ar kopijām
Arī ārpus tīmekļa saknes ir spēkā mazāko tiesību princips. Pierādījies sadalījums:
- Īpašnieks ir deploy lietotājs, nevis PHP process.
- Grupa ir PHP-FPM pūla grupa, kurai drīkst tikai lasīt; tiesības
640. - Nekādas rakstīšanas piekļuves PHP procesam. Lietojumprogrammai nav jāspēj mainīt savus piekļuves datus.
- Nekādu īstu vērtību repozitorijā: reģistrē tikai
.env.examplear vietturiem, īstais fails ir.gitignore. - Atsevišķas vērtības katrai videi: izstrāde, staging un ražošana izmanto dažādas piekļuves, lai noplūde testa vidē neatvērtu ražošanu.
chown deploy:shop-php /srv/www/shop/.env
chmod 640 /srv/www/shop/.env
# Pārbaudīt, vai fails kādreiz ir reģistrēts
git log --all --oneline -- .env
Ņemiet vērā arī kļūdu lapas. Ietvari atkļūdošanas režīmā daļēji rāda vides mainīgos un konfigurācijas vērtības; ražošanas sistēmā šim režīmam jābūt izslēgtam. Pārbaudiet to pēc katras izvietošanas, jo nepareiza vērtība pašā .env to var atkal ieslēgt.
Ja pēdējā komanda dod atradumus, piekļuves dati ir Git vēsturē un tiek uzskatīti par atklātiem, pat ja fails šodien ir prom. Kāpēc tas ir īpaši delikāti, ja .git mape atrodas serverī, apraksta Publiska .git mape: nenovērtēta datu noplūde. Pamatus par tiesībām skaidro ceļvedis Failu tiesības tīmekļa serverī.
Testa faili ar phpinfo() rāda vides mainīgos. Kas noslēpumus nodod kā vides mainīgos, tas tos izpauž ar aizmirstu testa failu. Fons ir rakstā phpinfo() faili: kāpēc tiem jāpazūd.
Pēc ielaušanās: piekļuves datu nomaiņa
Neviena bloķēšana neaizsargā pret uzbrucēju, kas serverī jau izpilda kodu. PHP procesam savu konfigurāciju jāspēj lasīt, tātad to var arī ievadīts kods tajā pašā procesā. Pēc PHP2Shell tāpēc ir spēkā: ja ielaušanos nevar izslēgt, visi piekļuves dati serverī jāuzskata par zināmiem.
Sakārtota nomaiņa aptver datubāzu paroles, pasta un SMTP piekļuves, ārējo pakalpojumu API atslēgas, lietojumprogrammas parakstu atslēgas un piekļuves glabāšanas pakalpojumiem. Secība un laiks jāplāno: kas vispirms nomaina un tad sakopj serveri, tas uzbrucējam, iespējams, jaunās vērtības atdod uzreiz.
Noplūdes kaitējumu ierobežojat jau iepriekš, katram noslēpumam ļaujot tikai tik daudz, cik vajadzīgs. Vietnes datubāzes lietotājam nevajag tiesības uz citām datubāzēm. Daudzu sniedzēju ārējo pakalpojumu API atslēgas var ierobežot ar atsevišķām funkcijām vai sūtītāju adresēm, piemēram, izveidot sūtījumus, bet neuzsākt izmaksas. Un katra lietojumprogramma saņem savas piekļuves, nevis vairākas vietnes dala vienu pasta kontu vai vienu atslēgu. Tad noplūde skar skaidri norobežotu jomu, un nomaiņa paliek pārskatāma.
Konteineru vidēs .env fails nepieder ne attēlam (image), ne publiski sasniedzamam reģistram. Izslēdziet to ar .dockerignore un noslēpumus nododiet tikai izpildes laikā ar platformas mehānismiem.
Ilgtermiņā vērts pievērsties centralizētām noslēpumu krātuvēm, kādas iesaka OWASP: noslēpumi vienā vietā, ar piekļuves žurnālu, regulāru nomaiņu un pēc iespējas īsu derīgumu.
Kā PHP SOS palīdz konkrēti?
- Mēs no ārpuses pārbaudām, vai jūsu vietņu konfigurācijas faili, kopijas un slēptie faili ir atverami.
- Mēs pārkārtojam tīmekļa sakni, tīmekļa servera bloķēšanu un failu tiesības tā, lai noslēpumi pa HTTP vairs nebūtu sasniedzami.
- Mēs pārbaudām repozitorijus un izvietošanas uz reģistrētiem piekļuves datiem.
- Pēc incidenta mēs plānojam un pavadām visu skarto piekļuvju nomaiņu pareizā secībā.
Šie darbi ir daļa no mūsu PHP tīmekļa serveru nostiprināšanas.
Biežāk uzdotie jautājumi
Vai .env fails tīmekļa saknē automātiski ir publisks?
Ne automātiski, bet bieži. Vai tas ir atverams, atkarīgs no tīmekļa servera konfigurācijas. Daudzas noklusējuma konfigurācijas aizsargā tikai .htaccess failus, nevis citus failus, kuru nosaukums sākas ar punktu. Tests ar curl rada skaidrību.
Vai vides mainīgie ir drošāki par .env failu?
Ne principā. OWASP norāda, ka vides mainīgie ir lasāmi visiem lietotāja procesiem un var parādīties žurnālos vai atmiņas attēlos. Tomēr tie ļauj izvairīties no faila tīmekļa saknē. Labāki ir centralizētas noslēpumu krātuves, kur vide tās atbalsta.
Ko darīt, ja .env fails bija atverams?
Visus tajā esošos piekļuves datus uzskatīt par zināmiem un nomainīt: datubāze, pasts, API, maksājumu pakalpojumi, lietojumprogrammas atslēgas. Pēc tam piekļuves žurnālos pārbaudīt, vai fails ir atvērts, un, ja ir personas dati, iesaistīt datu aizsardzības speciālistu.
Vai .env fails pieder Git repozitorijam?
Nē. Repozitorijā drīkst būt ne vairāk kā veidne bez īstām vērtībām, piemēram, .env.example. Īstais fails tiek izslēgts ar .gitignore un serverī nodrošināts atsevišķi.
Vai phpinfo() var izpaust piekļuves datus?
Jā. phpinfo() cita starpā rāda vides mainīgos un servera mainīgos. Ja tur ir noslēpumi, tie tiek izvadīti līdzi. Testa faili ar phpinfo() tāpēc nekad nedrīkst atrasties sasniedzamā sistēmā.