# Skydda inloggningsuppgifter och .env-filer rätt

> Skydda .env-filen: rätt webbrot, spärrar i webbservern, snäva filrättigheter, inga hemligheter i Git och utbyte efter en säkerhetsincident.

Källa: https://phpsos.de/sv/blog/env-dateien-schuetzen/  
Aktualitet: 2026-10-25  
Leverantör: PHP SOS, PHP-nödhjälp och serversäkerhet. Omedelbar hjälp via WhatsApp: https://wa.me/491736494914?text=Hej%20PHP%20SOS%2C%20vi%20beh%C3%B6ver%20hj%C3%A4lp%20med%20v%C3%A5r%20PHP-server.%20F%C3%B6retag%3A%20%E2%80%A6%20Webbplats%3A%20%E2%80%A6

**Kort sagt:** En .env-fil skyddar ni genom att den inte alls ligger i den offentligt nåbara katalogen: Webbroten pekar på en undermapp som `public/`, konfigurationen ligger en nivå ovanför. Dessutom spärrar webbservern alla filer med punkt i början, filen är bara läsbar för ägaren och PHP-processen och hör aldrig hemma i Git-repositoryt. Efter ett intrång räknas alla inloggningsuppgifter i den som kända och byts ut.

## Filen med nycklarna till huset

Moderna PHP-projekt lägger gärna sina hemligheter i en fil som heter `.env`: databaslösenord, åtkomst till e-postservern, API-nycklar för betal- och fraktleverantörer, nyckeln som applikationen signerar cookies med. Ramverk som Laravel och Symfony använder det mönstret, och många egenutvecklingar har tagit över det.

Idén är bra: Konfiguration och kod är åtskilda, och varje miljö får egna värden. Farligt blir det när filen hamnar i fel katalog. Ligger den i webbroten och webbservern inte spärrar den räcker ett enda anrop i webbläsaren för att läsa alla åtkomster på en gång.

Dessutom finns varianter med andra namn: `.env.local`, `.env.production`, `config.local.php` eller filer med inloggningsuppgifter till lagringstjänster. Det som här beskrivs för `.env` gäller alla filer där hemligheter står.

Sådana filer eftersöks ständigt av automatiserade skannrar. Det är ingen specialitet för enskilda angripare utan bakgrundsbrus på internet, liknande massskanningarna efter opatchade PHP-versioner.

## Var .env-filen bör ligga

Den mest verksamma åtgärden är strukturell: Webbservern får bara leverera den mapp som verkligen ska vara offentlig. I Laravel och Symfony är det mappen `public/`. Allt annat, alltså kod, konfiguration, loggar och `.env`, ligger ovanför och går över HTTP inte alls att adressera.

```text
/srv/www/shop/
├── .env              ← inte nåbar
├── config/
├── src/
├── vendor/
└── public/           ← enda webbroten
    ├── index.php
    └── assets/
```

I praktiken pekar webbroten ändå ofta på själva projektkatalogen, till exempel för att en webbhotellspanel föreskriver det eller för att en sökväg inte anpassades vid flytten. Kontrollera därför i webbserverkonfigurationen eller i panelen vart `root` respektive `DocumentRoot` pekar.

## Skydda .env-filen: spärr i webbservern som andra linje

Går webbroten inte att ändra, eller vill ni ha ett extra skydd, spärrar ni dolda filer i webbservern. Mappen `.well-known` måste då förbli nåbar, eftersom den bland annat används för utfärdande av certifikat.

```nginx
# Spärra alla filer och mappar med punkt i början utom .well-known
location ~ /\.(?!well-known/) {
    deny all;
    return 404;
}
```

```apache
# Spärra filer med punkt i början
<FilesMatch "^\.">
    Require all denied
</FilesMatch>
```

Ett svar med 404 i stället för 403 avslöjar inte att filen finns. Om spärren fungerar kontrollerar ni utifrån:

```bash
# Väntat: 403 eller 404, aldrig 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 två sista raderna är ingen slump: Kopior som `.env.bak` eller `.env.old` uppstår vid underhållsarbeten och glöms ofta bort. Mer om sådana kvarlevor står i [Backupfiler i webbroten](https://phpsos.de/sv/blog/backup-dateien-im-webroot/).

## Rättigheter, Git och hantering av kopior

Även utanför webbroten gäller principen om minsta möjliga rättigheter. En beprövad uppdelning:

1. **Ägare** är driftsättningsanvändaren, inte PHP-processen.
2. **Grupp** är PHP-FPM-poolens grupp, som bara får läsa; rättigheter `640`.
3. **Ingen skrivåtkomst** för PHP-processen. En applikation behöver inte kunna ändra sina egna inloggningsuppgifter.
4. **Inga riktiga värden i repositoryt:** Bara `.env.example` med platshållare checkas in, den riktiga filen står i `.gitignore`.
5. **Skilda värden per miljö:** Utveckling, staging och produktion använder olika åtkomster så att ett läckage i en testmiljö inte öppnar produktionen.

```bash
chown deploy:shop-php /srv/www/shop/.env
chmod 640 /srv/www/shop/.env
# Kontrollera om filen någonsin har checkats in
git log --all --oneline -- .env
```

Se också upp med felsidor. Ramverk visar i felsökningsläge delvis miljövariabler och konfigurationsvärden; i ett produktionssystem måste det läget vara avstängt. Kontrollera det efter varje driftsättning, för ett felaktigt värde i själva `.env` kan slå på det igen.

Ger det sista kommandot träffar står inloggningsuppgifterna i Git-historiken och räknas som röjda, även om filen saknas i dag. Varför det är särskilt känsligt när `.git`-mappen ligger på servern beskriver [Offentlig .git-mapp: ett underskattat dataläckage](https://phpsos.de/sv/blog/git-ordner-oeffentlich/). Grundläggande om rättigheter förklarar guiden [Filrättigheter på webbservern](https://phpsos.de/sv/ratgeber/dateirechte-webserver/).

> **Viktigt:**
> Testfiler med `phpinfo()` visar miljövariabler. Den som lämnar över hemligheter som miljövariabler röjer dem via en bortglömd testfil. Bakgrund finns i [phpinfo()-filer: varför de måste bort](https://phpsos.de/sv/blog/phpinfo-dateien-entfernen/).

## Efter ett intrång: byt ut inloggningsuppgifter

Ingen spärr skyddar mot en angripare som redan kör kod på servern. En PHP-process måste kunna läsa sin konfiguration, alltså kan inplanterad kod i samma process göra det också. Efter PHP2Shell gäller därför: Kan ett intrång inte uteslutas ska alla inloggningsuppgifter på servern behandlas som kända.

Ett ordnat utbyte omfattar databaslösenord, e-post- och SMTP-åtkomster, API-nycklar för externa tjänster, applikationens signeringsnycklar och åtkomster till lagringstjänster. Ordning och tidpunkt bör planeras: Den som byter först och sedan rensar servern ger kanske angriparen de nya värdena på köpet.

Skadan av ett läckage begränsar ni redan i förväg genom att varje hemlighet bara får göra så mycket som nödvändigt. Webbplatsens databasanvändare behöver inga rättigheter på andra databaser. API-nycklar för externa tjänster går hos många leverantörer att begränsa till enskilda funktioner eller avsändaradresser, till exempel skapa försändelser men inte initiera utbetalningar. Och varje applikation får egna åtkomster i stället för att flera webbplatser delar samma e-postkonto eller samma nyckel. Då berör ett läckage ett klart avgränsat område, och utbytet förblir överskådligt.

I containermiljöer hör `.env`-filen varken hemma i imagen eller i ett offentligt nåbart register. Utesluta den via `.dockerignore` och lämna över hemligheter först vid körtid via plattformens mekanismer.

På sikt är det värt att titta på centrala hemlighetslager, som OWASP rekommenderar: hemligheter på ett ställe, med åtkomstlogg, regelbundet utbyte och så kort giltighet som möjligt.

## Hur hjälper PHP SOS konkret?

- Vi kontrollerar utifrån om konfigurationsfiler, kopior och dolda filer på era webbplatser går att hämta.
- Vi ställer om webbrot, webbserverspärrar och filrättigheter så att hemligheter inte längre är nåbara över HTTP.
- Vi kontrollerar repositories och driftsättningar efter incheckade inloggningsuppgifter.
- Efter en incident planerar och följer vi utbytet av alla berörda åtkomster i rätt ordning.

Dessa arbeten är en del av vår [serverhärdning för PHP-webbservrar](https://phpsos.de/sv/leistungen/server-haertung/).


## Vanliga frågor

**Är en .env-fil i webbroten automatiskt offentlig?**  
Inte automatiskt, men ofta. Om den går att hämta beror på webbserverkonfigurationen. Många standardkonfigurationer skyddar bara .htaccess-filer, inte andra filer med punkt i början. Ett test med curl ger klarhet.

**Är miljövariabler säkrare än en .env-fil?**  
Inte i grunden. OWASP påpekar att miljövariabler är läsbara för alla användarens processer och kan dyka upp i loggar eller minnesavbilder. De undviker dock en fil i webbroten. Bättre är centrala hemlighetslager där miljön stöder det.

**Vad gör man om .env-filen gick att hämta?**  
Betrakta alla inloggningsuppgifter i den som kända och byt ut dem: databas, e-post, API:er, betaltjänster, applikationens nycklar. Kontrollera sedan i åtkomstloggarna om filen har hämtats och involvera vid personuppgifter dataskyddsombudet.

**Hör .env-filen hemma i Git-repositoryt?**  
Nej. I repositoryt hör högst en mall utan riktiga värden hemma, till exempel .env.example. Den riktiga filen utesluts via .gitignore och tillhandahålls separat på servern.

**Kan phpinfo() avslöja inloggningsuppgifter?**  
Ja. phpinfo() visar bland annat miljövariabler och servervariabler. Ligger hemligheter där skrivs de ut med. Testfiler med phpinfo() hör därför aldrig hemma på ett nåbart system.

## Källor

- [OWASP Secrets Management Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html)
- [Nginx-dokumentation](https://nginx.org/en/docs/)
- [Apache HTTP Server: dokumentation](https://httpd.apache.org/docs/)
