# Toegangsgegevens en .env-bestanden correct beveiligen

> .env-bestand beveiligen: juiste webroot, blokkades in de webserver, strikte bestandsrechten, geen geheimen in Git en vervanging na een beveiligingsincident.

Bron: https://phpsos.de/nl/blog/env-dateien-schuetzen/  
Stand: 25-10-2026  
Aanbieder: PHP SOS, PHP-noodhulp en serverbeveiliging. Directe hulp via WhatsApp: https://wa.me/491736494914?text=Hallo%20PHP%20SOS%2C%20wij%20hebben%20hulp%20nodig%20met%20onze%20PHP-server.%20Bedrijf%3A%20%E2%80%A6%20Website%3A%20%E2%80%A6

**Kort gezegd:** Een .env-bestand beveiligt u door het in de eerste plaats niet in de openbaar bereikbare map te zetten: de webroot wijst naar een submap zoals `public/`, de configuratie staat een niveau hoger. Daarnaast blokkeert de webserver alle bestanden met een punt vooraan, is het bestand alleen leesbaar voor eigenaar en PHP-proces en hoort het nooit in de Git-repository. Na een inbraak gelden alle daarin opgenomen toegangsgegevens als bekend en worden ze vervangen.

## Het bestand met de sleutels van het huis

Moderne PHP-projecten bewaren hun geheimen graag in een bestand met de naam `.env`: databasewachtwoord, toegang tot de mailserver, API-sleutels voor betaal- en verzenddiensten, de sleutel waarmee de applicatie cookies ondertekent. Frameworks zoals Laravel en Symfony gebruiken dit patroon, veel eigen ontwikkelingen hebben het overgenomen.

Het idee is goed: configuratie en code zijn gescheiden en elke omgeving krijgt eigen waarden. Gevaarlijk wordt het als het bestand in de verkeerde map terechtkomt. Staat het in de webroot en blokkeert de webserver het niet, dan volstaat één enkele aanroep in de browser om alle toegangen in één keer te lezen.

Daarbij komen varianten met andere namen: `.env.local`, `.env.production`, `config.local.php` of bestanden met toegangsgegevens tot opslagdiensten. Wat hier voor `.env` wordt beschreven, geldt voor alle bestanden waarin geheimen staan.

Zulke bestanden worden voortdurend door geautomatiseerde scanners gezocht. Dat is geen specialiteit van afzonderlijke aanvallers, maar achtergrondruis op het internet, vergelijkbaar met de massascans naar niet-gepatchte PHP-versies.

## Waar het .env-bestand hoort te staan

De effectiefste maatregel is structureel: de webserver mag alleen de map uitleveren die echt openbaar moet zijn. In Laravel en Symfony is dat de map `public/`. Al het andere, dus code, configuratie, logboeken en `.env`, staat daarboven en is via HTTP helemaal niet adresseerbaar.

```text
/srv/www/shop/
├── .env              ← niet bereikbaar
├── config/
├── src/
├── vendor/
└── public/           ← enige webroot
    ├── index.php
    └── assets/
```

In de praktijk wijst de webroot toch vaak naar de projectmap zelf, bijvoorbeeld omdat een hostingpaneel dat zo voorschrijft of omdat bij een verhuizing een pad niet is aangepast. Controleer daarom in de webserverconfiguratie of in het paneel waarheen `root` respectievelijk `DocumentRoot` wijst.

## .env-bestand beveiligen: blokkade in de webserver als tweede linie

Laat de webroot zich niet wijzigen, of wilt u een extra beveiliging, blokkeer dan verborgen bestanden in de webserver. De map `.well-known` moet daarbij bereikbaar blijven, omdat die onder meer wordt gebruikt voor het uitgeven van certificaten.

```nginx
# Alle bestanden en mappen met een punt vooraan blokkeren, behalve .well-known
location ~ /\.(?!well-known/) {
    deny all;
    return 404;
}
```

```apache
# Bestanden met een punt vooraan blokkeren
<FilesMatch "^\.">
    Require all denied
</FilesMatch>
```

Een antwoord met 404 in plaats van 403 verraadt niet dat het bestand bestaat. Of de blokkade werkt, controleert u van buitenaf:

```bash
# Verwacht: 403 of 404, nooit 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
```

De laatste twee regels zijn geen toeval: kopieën zoals `.env.bak` of `.env.old` ontstaan bij onderhoudswerk en worden vaak vergeten. Meer over zulke overblijfselen staat in [Back-upbestanden in de webroot](https://phpsos.de/nl/blog/backup-dateien-im-webroot/).

## Rechten, Git en de omgang met kopieën

Ook buiten de webroot geldt het principe van de minste rechten. Een beproefde indeling:

1. **Eigenaar** is de deploygebruiker, niet het PHP-proces.
2. **Groep** is de groep van de PHP-FPM-pool, die alleen mag lezen; rechten `640`.
3. **Geen schrijftoegang** voor het PHP-proces. Een applicatie hoeft haar eigen toegangsgegevens niet te kunnen wijzigen.
4. **Geen echte waarden in de repository:** alleen `.env.example` met plaatshouders wordt ingecheckt, het echte bestand staat in `.gitignore`.
5. **Gescheiden waarden per omgeving:** ontwikkeling, staging en productie gebruiken verschillende toegangen, zodat een lek in een testomgeving de productie niet opent.

```bash
chown deploy:shop-php /srv/www/shop/.env
chmod 640 /srv/www/shop/.env
# Controleren of het bestand ooit is ingecheckt
git log --all --oneline -- .env
```

Let ook op foutpagina's. Frameworks tonen in de debugmodus soms omgevingsvariabelen en configuratiewaarden; op een productiesysteem moet deze modus zijn uitgeschakeld. Controleer dat na elke deployment, want een verkeerde waarde in de `.env` zelf kan hem weer inschakelen.

Levert de laatste opdracht treffers op, dan staan de toegangsgegevens in de Git-geschiedenis en gelden ze als blootgelegd, ook als het bestand er vandaag niet meer is. Waarom dat bijzonder gevoelig is als de `.git`-map op de server staat, beschrijft [Openbare .git-map: een onderschat datalek](https://phpsos.de/nl/blog/git-ordner-oeffentlich/). Basisprincipes over rechten legt de gids [Bestandsrechten op de webserver](https://phpsos.de/nl/ratgeber/dateirechte-webserver/) uit.

> **Belangrijk:**
> Testbestanden met `phpinfo()` tonen omgevingsvariabelen. Wie geheimen als omgevingsvariabelen doorgeeft, verraadt ze via een vergeten testbestand. Achtergronden staan in [phpinfo()-bestanden: waarom ze moeten verdwijnen](https://phpsos.de/nl/blog/phpinfo-dateien-entfernen/).

## Na een inbraak: toegangsgegevens vervangen

Geen blokkade beschermt tegen een aanvaller die al code op de server uitvoert. Een PHP-proces moet zijn configuratie kunnen lezen, dus binnengesmokkelde code in hetzelfde proces kan dat ook. Na PHP2Shell geldt daarom: kan een inbraak niet worden uitgesloten, behandel dan alle toegangsgegevens op de server als bekend.

Een ordelijke vervanging omvat databasewachtwoorden, mail- en SMTP-toegangen, API-sleutels van externe diensten, ondertekeningssleutels van de applicatie en toegangen tot opslagdiensten. Volgorde en tijdstip moeten worden gepland: wie eerst vervangt en dan de server opschoont, geeft de aanvaller mogelijk meteen de nieuwe waarden mee.

De schade van een lek beperkt u al vooraf, doordat elk geheim alleen zoveel mag als nodig is. De databasegebruiker van de website heeft geen rechten op andere databases nodig. API-sleutels van externe diensten zijn bij veel aanbieders te beperken tot afzonderlijke functies of afzenderadressen, bijvoorbeeld zendingen aanmaken maar geen uitbetalingen initiëren. En elke applicatie krijgt eigen toegangen, in plaats van dat meerdere websites hetzelfde mailaccount of dezelfde sleutel delen. Dan betreft een lek een duidelijk afgebakend gebied en blijft de vervanging overzichtelijk.

In containeromgevingen hoort het `.env`-bestand noch in de image noch in een openbaar bereikbare registry. Sluit het uit via `.dockerignore` en geef geheimen pas tijdens de uitvoering door via de mechanismen van het platform.

Op de lange termijn loont een blik op centrale secretopslagen, zoals OWASP ze adviseert: geheimen op één plek, met toegangslogboek, regelmatige vervanging en een zo kort mogelijke geldigheid.

## Hoe helpt PHP SOS concreet?

- Wij controleren van buitenaf of configuratiebestanden, kopieën en verborgen bestanden van uw websites op te halen zijn.
- Wij zetten webroot, webserverblokkades en bestandsrechten zo om dat geheimen niet meer via HTTP bereikbaar zijn.
- Wij controleren repositories en deployments op ingecheckte toegangsgegevens.
- Na een incident plannen en begeleiden wij de vervanging van alle getroffen toegangen in de juiste volgorde.

Deze werkzaamheden zijn onderdeel van onze [serverhardening voor PHP-webservers](https://phpsos.de/nl/leistungen/server-haertung/).


## Veelgestelde vragen

**Is een .env-bestand in de webroot automatisch openbaar?**  
Niet automatisch, maar vaak wel. Of het op te halen is, hangt af van de webserverconfiguratie. Veel standaardconfiguraties beschermen alleen .htaccess-bestanden, niet andere bestanden met een punt vooraan. Een test met curl brengt duidelijkheid.

**Zijn omgevingsvariabelen veiliger dan een .env-bestand?**  
Niet principieel. OWASP wijst erop dat omgevingsvariabelen voor alle processen van de gebruiker leesbaar zijn en in logboeken of geheugendumps kunnen opduiken. Ze vermijden wel een bestand in de webroot. Beter zijn centrale secretopslagen, waar de omgeving die ondersteunt.

**Wat te doen als het .env-bestand op te halen was?**  
Alle daarin opgenomen toegangsgegevens als bekend beschouwen en vervangen: database, mail, API's, betaaldiensten, sleutels van de applicatie. Controleer daarna in de toegangslogboeken of het bestand is opgehaald en betrek bij persoonsgegevens de functionaris voor gegevensbescherming.

**Hoort het .env-bestand in de Git-repository?**  
Nee. In de repository hoort hooguit een sjabloon zonder echte waarden, bijvoorbeeld .env.example. Het echte bestand wordt via .gitignore uitgesloten en apart op de server geplaatst.

**Kan phpinfo() toegangsgegevens verraden?**  
Ja. phpinfo() toont onder meer omgevingsvariabelen en servervariabelen. Staan er geheimen in, dan worden ze mee weergegeven. Testbestanden met phpinfo() horen daarom nooit op een bereikbaar systeem.

## Bronnen

- [OWASP Secrets Management Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html)
- [Nginx-documentatie](https://nginx.org/en/docs/)
- [Apache HTTP Server: documentatie](https://httpd.apache.org/docs/)
