# Ispravno zaštititi pristupne podatke i .env datoteke

> Zaštita .env datoteke: ispravan webroot, blokade u web-poslužitelju, uska prava datoteka, bez tajni u Gitu i zamjena podataka nakon sigurnosnog incidenta.

Izvor: https://phpsos.de/hr/blog/env-dateien-schuetzen/  
Stanje: 25.10.2026  
Pružatelj: PHP SOS, PHP hitna pomoć i sigurnost poslužitelja. Hitna pomoć putem WhatsAppa: https://wa.me/491736494914?text=Pozdrav%20PHP%20SOS%2C%20trebamo%20pomo%C4%87%20s%20na%C5%A1im%20PHP%20poslu%C5%BEiteljem.%20Tvrtka%3A%20%E2%80%A6%20Web-stranica%3A%20%E2%80%A6

**Ukratko:** .env datoteku štitite tako da uopće ne leži u javno dostupnom direktoriju: webroot pokazuje na poddirektorij poput `public/`, a konfiguracija leži jednu razinu iznad. Uz to web-poslužitelj blokira sve datoteke s točkom na početku, datoteka je čitljiva samo vlasniku i PHP procesu i nikad ne pripada u Git repozitorij. Nakon provale svi pristupni podaci u njoj smatraju se poznatima i zamjenjuju se.

## Datoteka s ključevima kuće

Moderni PHP projekti svoje tajne rado pohranjuju u datoteku naziva `.env`: lozinka baze podataka, pristup poslužitelju e-pošte, API ključevi za usluge plaćanja i dostave, ključ kojim aplikacija potpisuje kolačiće. Frameworci poput Laravela i Symfonyja koriste taj uzorak, a mnoge vlastite izvedbe su ga preuzele.

Ideja je dobra: konfiguracija i kod su odvojeni, a svako okruženje dobiva vlastite vrijednosti. Opasno postaje kad datoteka završi u pogrešnom direktoriju. Ako leži u webrootu, a web-poslužitelj je ne blokira, dovoljan je jedan poziv u pregledniku da se odjednom pročitaju svi pristupi.

Tome se pridružuju varijante s drugim nazivima: `.env.local`, `.env.production`, `config.local.php` ili datoteke s pristupnim podacima za usluge pohrane. Ono što je ovdje opisano za `.env` vrijedi za sve datoteke u kojima stoje tajne.

Takve datoteke automatizirani skeneri neprestano traže. To nije specijalnost pojedinih napadača, nego osnovna buka na internetu, slično masovnim skeniranjima nezakrpanih PHP verzija.

## Gdje bi trebala ležati .env datoteka

Najučinkovitija mjera je strukturalna: web-poslužitelj smije isporučivati samo mapu koja doista treba biti javna. U Laravelu i Symfonyju to je mapa `public/`. Sve ostalo, dakle kod, konfiguracija, zapisnici i `.env`, leži iznad nje i preko HTTP-a uopće se ne može adresirati.

```text
/srv/www/shop/
├── .env              ← nedostupno
├── config/
├── src/
├── vendor/
└── public/           ← jedini webroot
    ├── index.php
    └── assets/
```

U praksi webroot ipak često pokazuje na sam direktorij projekta, primjerice jer to zadaje hosting panel ili jer pri selidbi putanja nije prilagođena. Zato u konfiguraciji web-poslužitelja ili u panelu provjerite kamo pokazuje `root` odnosno `DocumentRoot`.

## Zaštita .env datoteke: blokada u web-poslužitelju kao druga linija

Ako se webroot ne može promijeniti ili želite dodatnu zaštitu, blokirajte skrivene datoteke u web-poslužitelju. Mapa `.well-known` pritom mora ostati dostupna jer se među ostalim koristi za izdavanje certifikata.

```nginx
# Blokirati sve datoteke i mape s točkom na početku, osim .well-known
location ~ /\.(?!well-known/) {
    deny all;
    return 404;
}
```

```apache
# Blokirati datoteke s točkom na početku
<FilesMatch "^\.">
    Require all denied
</FilesMatch>
```

Odgovor 404 umjesto 403 ne otkriva da datoteka postoji. Djeluje li blokada, provjerite izvana:

```bash
# Očekuje se: 403 ili 404, nikada 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
```

Posljednja dva retka nisu slučajna: kopije poput `.env.bak` ili `.env.old` nastaju pri radovima održavanja i često se zaborave. Više o takvim ostacima stoji u članku [Sigurnosne kopije u webrootu](https://phpsos.de/hr/blog/backup-dateien-im-webroot/).

## Prava, Git i postupanje s kopijama

I izvan webroota vrijedi načelo najmanjih prava. Dokazana podjela:

1. **Vlasnik** je korisnik za isporuku (deploy), a ne PHP proces.
2. **Grupa** je grupa PHP-FPM poola, koja smije samo čitati; prava `640`.
3. **Bez pristupa pisanju** za PHP proces. Aplikacija ne mora moći mijenjati vlastite pristupne podatke.
4. **Bez stvarnih vrijednosti u repozitoriju:** u repozitorij se unosi samo `.env.example` s rezerviranim mjestima, a stvarna datoteka stoji u `.gitignore`.
5. **Odvojene vrijednosti po okruženju:** razvoj, staging i produkcija koriste različite pristupe kako curenje u testnom okruženju ne bi otvorilo produkciju.

```bash
chown deploy:shop-php /srv/www/shop/.env
chmod 640 /srv/www/shop/.env
# Provjeriti je li datoteka ikada unesena u repozitorij
git log --all --oneline -- .env
```

Pazite i na stranice s pogreškama. Frameworci u debug načinu ponekad prikazuju varijable okruženja i konfiguracijske vrijednosti; na produkcijskom sustavu taj način mora biti isključen. Provjerite to nakon svake isporuke, jer pogrešna vrijednost u samoj `.env` može ga ponovno uključiti.

Ako zadnja naredba vrati pogotke, pristupni podaci nalaze se u Git povijesti i smatraju se otkrivenima, čak i ako datoteke danas nema. Zašto je to osobito ozbiljno kad direktorij `.git` leži na poslužitelju, opisuje [Javni .git direktorij: podcijenjeno curenje podataka](https://phpsos.de/hr/blog/git-ordner-oeffentlich/). Osnove o pravima objašnjava vodič [Prava datoteka na web-poslužitelju](https://phpsos.de/hr/ratgeber/dateirechte-webserver/).

> **Važno:**
> Testne datoteke s `phpinfo()` prikazuju varijable okruženja. Tko tajne predaje kao varijable okruženja, odaje ih zaboravljenom testnom datotekom. Pozadina stoji u članku [phpinfo() datoteke: zašto moraju nestati](https://phpsos.de/hr/blog/phpinfo-dateien-entfernen/).

## Nakon provale: zamijeniti pristupne podatke

Nijedna blokada ne štiti od napadača koji već izvršava kod na poslužitelju. PHP proces mora moći čitati svoju konfiguraciju, pa to može i ubačeni kod u istom procesu. Nakon PHP2Shella stoga vrijedi: ako se provala ne može isključiti, svi pristupni podaci na poslužitelju tretiraju se kao poznati.

Uredna zamjena obuhvaća lozinke baza podataka, pristupe e-pošti i SMTP-u, API ključeve vanjskih usluga, ključeve za potpis aplikacije i pristupe uslugama pohrane. Redoslijed i trenutak trebaju biti planirani: tko najprije zamijeni, a tek zatim očisti poslužitelj, napadaču možda odmah preda i nove vrijednosti.

Štetu od curenja ograničavate već unaprijed tako da svaka tajna smije samo onoliko koliko je nužno. Korisnik baze podataka web-stranice ne treba prava na druge baze. API ključevi vanjskih usluga kod mnogih se pružatelja mogu ograničiti na pojedine funkcije ili adrese pošiljatelja, primjerice stvaranje pošiljki, ali ne i pokretanje isplata. I svaka aplikacija dobiva vlastite pristupe, umjesto da više web-stranica dijeli isti račun e-pošte ili isti ključ. Tada curenje pogađa jasno omeđeno područje, a zamjena ostaje pregledna.

U okruženjima containera `.env` datoteka ne pripada ni u image ni u javno dostupan registry. Isključite je pomoću `.dockerignore` i tajne predajte tek za vrijeme rada mehanizmima platforme.

Dugoročno vrijedi pogledati središnja spremišta tajni, kakva preporučuje OWASP: tajne na jednom mjestu, sa zapisnikom pristupa, redovitom zamjenom i što kraćom valjanošću.

## Kako PHP SOS konkretno pomaže?

- Izvana provjeravamo jesu li konfiguracijske datoteke, kopije i skrivene datoteke Vaših web-stranica dostupne.
- Webroot, blokade web-poslužitelja i prava datoteka postavljamo tako da tajne više nisu dostupne preko HTTP-a.
- Provjeravamo repozitorije i isporuke u potrazi za unesenim pristupnim podacima.
- Nakon incidenta planiramo i pratimo zamjenu svih pogođenih pristupa ispravnim redoslijedom.

Ovi radovi dio su našeg [ojačavanja poslužitelja za PHP web-poslužitelje](https://phpsos.de/hr/leistungen/server-haertung/).


## Česta pitanja

**Je li .env datoteka u webrootu automatski javna?**  
Ne automatski, ali često. Je li dostupna, ovisi o konfiguraciji web-poslužitelja. Mnoge zadane konfiguracije štite samo .htaccess datoteke, a ne druge datoteke s točkom na početku. Test pomoću curl-a daje jasnoću.

**Jesu li varijable okruženja sigurnije od .env datoteke?**  
Ne u načelu. OWASP upozorava da su varijable okruženja čitljive svim procesima korisnika i da se mogu pojaviti u zapisnicima ili ispisima memorije. Ipak izbjegavaju datoteku u webrootu. Bolja su središnja spremišta tajni, gdje ih okruženje podržava.

**Što učiniti ako je .env datoteka bila dostupna?**  
Sve pristupne podatke u njoj smatrati poznatima i zamijeniti ih: baza podataka, e-pošta, API-ji, usluge plaćanja, ključevi aplikacije. Zatim u pristupnim zapisnicima provjeriti je li datoteka dohvaćena, a kod osobnih podataka uključiti službenika za zaštitu podataka.

**Pripada li .env datoteka u Git repozitorij?**  
Ne. U repozitorij najviše pripada predložak bez stvarnih vrijednosti, primjerice .env.example. Stvarna datoteka isključuje se pomoću .gitignore i na poslužitelju se stavlja na raspolaganje odvojeno.

**Može li phpinfo() otkriti pristupne podatke?**  
Da. phpinfo() među ostalim prikazuje varijable okruženja i poslužiteljske varijable. Ako su tamo tajne, ispisuju se zajedno s njima. Testne datoteke s phpinfo() zato nikad ne pripadaju na dostupan sustav.

## Izvori

- [OWASP Secrets Management Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html)
- [Nginx dokumentacija](https://nginx.org/en/docs/)
- [Apache HTTP Server: dokumentacija](https://httpd.apache.org/docs/)
