Lühidalt: .env-faili kaitsete nii, et see ei asugi avalikult kättesaadavas kataloogis: veebijuurkataloog viitab alamkaustale, nagu public/, konfiguratsioon asub ühe taseme kõrgemal. Lisaks blokeerib veebiserver kõik punktiga algavad failid, fail on loetav ainult omanikule ja PHP protsessile ning ei kuulu kunagi Giti repositooriumi. Pärast sissemurdmist loetakse kõiki selles olevaid ligipääsuandmeid teadaolevaks ja need vahetatakse välja.
Fail maja võtmetega
Kaasaegsed PHP-projektid hoiavad oma saladusi meelsasti failis nimega .env: andmebaasi parool, ligipääs meiliserverile, makse- ja saatmisteenuste API-võtmed, võti, millega rakendus küpsiseid allkirjastab. Raamistikud, nagu Laravel ja Symfony, kasutavad seda mustrit, paljud omaarendused on selle üle võtnud.
Idee on hea: konfiguratsioon ja kood on lahus ning iga keskkond saab oma väärtused. Ohtlikuks muutub see siis, kui fail satub valesse kausta. Kui see asub veebijuurkataloogis ja veebiserver seda ei blokeeri, piisab ühest päringust brauseris, et lugeda kõik ligipääsud korraga.
Lisaks on variandid teiste nimedega: .env.local, .env.production, config.local.php või failid salvestusteenuste ligipääsuandmetega. Mis siin .env kohta kirjeldatud, kehtib kõigi failide kohta, milles saladusi on.
Selliseid faile otsivad pidevalt automatiseeritud skannerid. See ei ole üksikute ründajate eripära, vaid interneti taustamüra, sarnaselt paikamata PHP versioonide massskaneerimisele.
Kus .env-fail peaks asuma
Tõhusaim meede on struktuurne: veebiserver tohib edastada ainult kausta, mis peabki olema avalik. Laravelis ja Symfonys on selleks kaust public/. Kõik muu, see tähendab kood, konfiguratsioon, logid ja .env, asub kõrgemal ja ei ole HTTP kaudu üldse adresseeritav.
/srv/www/shop/
├── .env ← ei ole kättesaadav
├── config/
├── src/
├── vendor/
└── public/ ← ainus veebijuurkataloog
├── index.php
└── assets/
Praktikas viitab veebijuurkataloog sellest hoolimata sageli projektikataloogile endale, näiteks kuna hostingupaneel nõuab seda või kuna kolimisel jäi tee kohandamata. Kontrollige seetõttu veebiserveri konfiguratsioonist või paneelist, kuhu root vastavalt DocumentRoot viitab.
.env-faili kaitsmine: blokeering veebiserveris teise liinina
Kui veebijuurkataloogi muuta ei saa või soovite täiendavat kaitset, blokeerige peidetud failid veebiserveris. Kaust .well-known peab seejuures jääma kättesaadavaks, sest seda kasutatakse muu hulgas sertifikaatide väljastamiseks.
# Blokeeri kõik punktiga algavad failid ja kaustad, välja arvatud .well-known
location ~ /\.(?!well-known/) {
deny all;
return 404;
}
# Blokeeri punktiga algavad failid
<FilesMatch "^\.">
Require all denied
</FilesMatch>
Vastus 404 403 asemel ei reeda, et fail on olemas. Kas blokeering toimib, kontrollite väljastpoolt:
# Oodatud: 403 või 404, mitte kunagi 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
Kaks viimast rida ei ole juhus: koopiad, nagu .env.bak või .env.old, tekivad hooldustööde käigus ja unustatakse sageli. Rohkem selliste jäänukite kohta on artiklis Varundusfailid veebijuurkataloogis.
Õigused, Git ja koopiatega ümberkäimine
Ka väljaspool veebijuurkataloogi kehtib vähima õiguse põhimõte. End tõestanud jaotus:
- Omanik on deploy-kasutaja, mitte PHP protsess.
- Grupp on PHP-FPM-i pooli grupp, kes tohib ainult lugeda; õigused
640. - Kirjutusligipääsu ei ole PHP protsessil. Rakendus ei pea suutma oma ligipääsuandmeid muuta.
- Repositooriumis ei ole päris väärtusi: Sisse registreeritakse ainult
.env.examplekohatäitjatega, päris fail on failis.gitignore. - Eraldi väärtused keskkonna kaupa: Arendus, staging ja tootmine kasutavad erinevaid ligipääse, et leke testkeskkonnas ei avaks tootmist.
chown deploy:shop-php /srv/www/shop/.env
chmod 640 /srv/www/shop/.env
# Kontrolli, kas fail on kunagi sisse registreeritud
git log --all --oneline -- .env
Pöörake tähelepanu ka vealehtedele. Raamistikud näitavad silumisrežiimis osaliselt keskkonnamuutujaid ja konfiguratsiooniväärtusi; tootmissüsteemis peab see režiim olema välja lülitatud. Kontrollige seda pärast iga juurutamist, sest vale väärtus .env-is endas võib selle uuesti sisse lülitada.
Kui viimane käsk annab tabamusi, asuvad ligipääsuandmed Giti ajaloos ja loetakse avalikustatuks, isegi kui faili täna enam ei ole. Miks see on eriti tundlik, kui .git-kaust asub serveris, kirjeldab Avalik .git-kaust: alahinnatud andmeleke. Õiguste põhialused selgitab juhend Failiõigused veebiserveris.
Testfailid phpinfo()-ga näitavad keskkonnamuutujaid. Kes annab saladusi edasi keskkonnamuutujatena, reedab need unustatud testfaili kaudu. Taust on artiklis phpinfo()-failid: miks need peavad kaduma.
Pärast sissemurdmist: ligipääsuandmete vahetamine
Ükski blokeering ei kaitse ründaja eest, kes juba serveris koodi käivitab. PHP protsess peab oma konfiguratsiooni lugema suutma, seega suudab seda ka samas protsessis sissetoodud kood. Pärast PHP2Shelli kehtib seetõttu: kui sissemurdmist ei saa välistada, tuleb kõiki serveris olevaid ligipääsuandmeid käsitleda teadaolevatena.
Korrapärane vahetus hõlmab andmebaasiparoole, meili- ja SMTP-ligipääse, väliste teenuste API-võtmeid, rakenduse allkirjastamisvõtmeid ja ligipääse salvestusteenustele. Järjekord ja ajahetk peaksid olema planeeritud: kes vahetab kõigepealt ja puhastab seejärel serveri, annab ründajale uued väärtused võib-olla kohe kaasa.
Lekke kahju piirate juba ette, andes igale saladusele ainult nii palju õigusi kui vaja. Veebisaidi andmebaasikasutaja ei vaja õigusi teistele andmebaasidele. Väliste teenuste API-võtmeid saab paljudel pakkujatel piirata üksikute funktsioonide või saatja aadressidega, näiteks saadetiste loomine, kuid mitte väljamaksete algatamine. Ja iga rakendus saab oma ligipääsud, selle asemel et mitu veebisaiti jagaks sama meilikontot või sama võtit. Siis puudutab leke selgelt piiritletud ala ja vahetus jääb ülevaatlikuks.
Konteinerikeskkondades ei kuulu .env-fail ei pilti ega avalikult kättesaadavasse registrisse. Jätke see välja failiga .dockerignore ja andke saladused edasi alles töö ajal platvormi mehhanismide kaudu.
Pikemas perspektiivis tasub vaadata kesksete saladusehoidlate poole, nagu OWASP neid soovitab: saladused ühes kohas, juurdepääsulogi, regulaarse vahetuse ja võimalikult lühikese kehtivusega.
Kuidas PHP SOS konkreetselt aitab?
- Me kontrollime väljastpoolt, kas konfiguratsioonifailid, koopiad ja peidetud failid teie veebisaitidel on kättesaadavad.
- Me seadistame veebijuurkataloogi, veebiserveri blokeeringud ja failiõigused nii, et saladused ei ole enam HTTP kaudu kättesaadavad.
- Me kontrollime repositooriume ja juurutusi sisse registreeritud ligipääsuandmete suhtes.
- Pärast intsidenti planeerime ja toetame kõigi mõjutatud ligipääsude vahetamist õiges järjekorras.
Need tööd kuuluvad meie PHP veebiserverite kõvendamise juurde.
Korduma kippuvad küsimused
Kas veebijuurkataloogis olev .env-fail on automaatselt avalik?
Mitte automaatselt, kuid sageli. See, kas see on kättesaadav, sõltub veebiserveri konfiguratsioonist. Paljud vaikekonfiguratsioonid kaitsevad ainult .htaccess-faile, mitte muid punktiga algavaid faile. Test käsuga curl toob selguse.
Kas keskkonnamuutujad on turvalisemad kui .env-fail?
Mitte põhimõtteliselt. OWASP juhib tähelepanu, et keskkonnamuutujad on kasutaja kõigile protsessidele loetavad ja võivad ilmuda logides või mälutõmmistes. Need väldivad aga faili veebijuurkataloogis. Parem on kesksed saladusehoidlad, kus keskkond neid toetab.
Mida teha, kui .env-fail oli kättesaadav?
Pidage kõiki selles sisalduvaid ligipääsuandmeid teadaolevaks ja vahetage need välja: andmebaas, meil, API-d, makseteenused, rakenduse võtmed. Seejärel kontrollige juurdepääsulogidest, kas faili on päritud, ja kaasake isikuandmete puhul andmekaitsespetsialist.
Kas .env-fail kuulub Giti repositooriumi?
Ei. Repositooriumi kuulub ülimalt mall ilma päris väärtusteta, näiteks .env.example. Päris fail jäetakse .gitignore kaudu välja ja pannakse serveris eraldi kättesaadavaks.
Kas phpinfo() võib ligipääsuandmeid reeta?
Jah. phpinfo() näitab muu hulgas keskkonnamuutujaid ja servermuutujaid. Kui saladused asuvad seal, väljastatakse need kaasa. Testfailid phpinfo()-ga ei kuulu seetõttu kunagi kättesaadavale süsteemile.