Ghid de securitate · Moldova

Ce headere de securitate HTTP configurez în nginx?

Headerele de securitate sunt instrucțiuni pe care serverul le dă browserului: ce scripturi are voie să ruleze, dacă pagina poate fi încadrată de alt site, ce informații trimite mai departe. Costă cinci linii în nginx și închid clase întregi de atacuri.

Actualizat la

Răspuns scurt

  1. Configurezi în nginx un set de headere de securitate HTTP care spun browserului ce are voie să facă pagina: Content-Security-Policy, X-Content-Type-Options, Referrer-Policy, Permissions-Policy și frame-ancestors.
  2. Content-Security-Policy o pornești în modul Report-Only, culegi rapoartele câteva săptămâni și abia apoi o impui, ca să nu rupi propriile scripturi.
  3. X-Content-Type-Options: nosniff și frame-ancestors 'none' sau 'self' se pot activa din prima zi, fără risc.
  4. Dezactivezi versiunea din antetul Server cu server_tokens off și scoți antetele care dezvăluie tehnologia, precum X-Powered-By.
  5. Verifici rezultatul cu curl -I după fiecare deploy, fiindcă un bloc location cu propriul add_header șterge headerele moștenite.
Fără risc din prima zi
nosniff, frame-ancestors, Referrer-Policy, Permissions-Policy
Cu perioadă de test
Content-Security-Policy-Report-Only, apoi CSP impusă
Capcana nginx
add_header într-un location anulează add_header din server
Verificare
curl -sI https://exemplu.md | grep -iE 'content-security|x-content|referrer|permissions'

Ce închide fiecare header

Content-Security-Policy limitează sursele de scripturi, stiluri, imagini și conexiuni, deci un script injectat prin XSS nu se mai execută sau nu mai poate trimite datele nicăieri. frame-ancestors, directiva CSP care înlocuiește X-Frame-Options, împiedică încadrarea site-ului în iframe de pe alt domeniu, adică clickjacking-ul. X-Content-Type-Options: nosniff oprește browserul să „ghicească” tipul unui fișier și să execute ca script ceva servit ca text. Referrer-Policy controlează ce URL trimiți mai departe, iar Permissions-Policy închide camera, microfonul și geolocația unde nu sunt folosite.

CSP se construiește, nu se copiază

O politică copiată de pe un blog blochează scriptul de plăți, widgetul de chat sau fontul de la un CDN și afli de la clienți. Pornești cu Content-Security-Policy-Report-Only și rapoarte către un endpoint al tău: browserele raportează ce ar fi blocat, fără să blocheze. După două-trei săptămâni ai lista reală de surse — propriul domeniu, procesatorul de plăți, analitica, CDN-ul de fonturi. Scrii politica pe ea, evitând 'unsafe-inline' prin nonce sau hash, și abia apoi treci pe antetul impus.

  • Report-Only cu report-uri către un endpoint propriu
  • lista de surse din rapoarte, nu din presupuneri
  • nonce sau hash în loc de 'unsafe-inline' pentru scripturi
  • object-src 'none' și base-uri 'self' aproape întotdeauna

Capcana add_header și verificarea

În nginx, directivele add_header se moștenesc din server în location doar dacă blocul location nu are niciun add_header propriu. De îndată ce adaugi un Cache-Control într-un location pentru fișiere statice, toate headerele de securitate dispar de pe acele răspunsuri. Soluția e un fișier include cu toate headerele, inclus explicit în fiecare location care definește altele, sau modulul headers-more. Verifici cu curl -I pe pagina principală, pe un fișier static și pe o pagină de eroare — toate trei cu setul complet — și pui verificarea în pipeline.

Headere de securitate HTTP recomandate pentru un site de producție
HeaderValoare recomandatăCe previneRisc la activare
Content-Security-Policydefault-src 'self'; script-src 'self' 'nonce-…'; object-src 'none'; frame-ancestors 'none'; base-uri 'self'XSS, clickjacking, injecție de resursemare fără Report-Only
X-Content-Type-Optionsnosniffexecuția unui fișier cu tip greșitniciunul
Referrer-Policystrict-origin-when-cross-originscurgerea URL-urilor cu tokenuriniciunul
Permissions-Policycamera=(), microphone=(), geolocation=()acces la senzori din scripturi injectatemic, dacă nu le folosești
Strict-Transport-Securitymax-age=300 în prima săptămână, apoi 31536000; includeSubDomains, doar pe blocul HTTPSdegradarea la HTTPvezi pagina despre HTTPS și HSTS
Server / X-Powered-Byserver_tokens off; antetul X-Powered-By eliminatidentificarea versiunilor de scanereniciunul

Comenzi și configurări

/etc/nginx/snippets/security-headers.conf
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
# HSTS NU se pune aici: se adaugă doar în blocul HTTPS și doar după perioada de test
# (începe cu max-age=300 o săptămână) — vezi pagina despre HTTPS și HSTS.

# CSP-ul de blocare începe cu directivele fără risc — acestea NU au nevoie de perioadă de test
add_header Content-Security-Policy "frame-ancestors 'none'; base-uri 'self'; object-src 'none'" always;
add_header X-Frame-Options "DENY" always;

# etapa 2: restul politicii, deocamdată doar raportare
add_header Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self' https://plati.exemplu.md; img-src 'self' data:; style-src 'self' 'unsafe-inline'; object-src 'none'; frame-ancestors 'none'; base-uri 'self'; report-uri /csp-report" always;
Includerea în server ȘI în fiecare location cu add_header propriu
server {
    server_tokens off;
    include snippets/security-headers.conf;

    location ~* \.(css|js|woff2|png|svg)$ {
        add_header Cache-Control "public, max-age=31536000, immutable";
        include snippets/security-headers.conf;   # altfel dispar aici
    }

    location = /csp-report {
        access_log /var/log/nginx/csp.log;
        return 204;
    }
}
Verificare după deploy
for u in / /static/app.js /pagina-inexistenta; do
  echo "== $u"; curl -sI "https://exemplu.md$u" | grep -iE '^(content-security|x-content-type|referrer|permissions|strict-transport|server):'
done

Exemple din practică

Portal al unei instituții din Chișinău

Un audit extern a găsit că portalul putea fi încadrat în iframe de pe orice domeniu și că antetul Server afișa versiunea exactă de nginx. Adăugarea frame-ancestors 'none', nosniff și server_tokens off a durat o oră; retestul nu a mai avut observații.

Magazin online din Bălți cu plăți prin procesator extern

O CSP copiată dintr-un articol a blocat scriptul procesatorului de plăți, iar comenzile au căzut la zero timp de o oră. Refăcută în Report-Only, cu sursele culese din rapoarte două săptămâni, politica impusă a trecut fără incident.

Aplicație SaaS din Cahul, pentru un client german

Chestionarul de securitate al clientului cerea lista headerelor și dovada unei CSP fără 'unsafe-inline'. Echipa a trecut scripturile inline pe nonce generat la fiecare cerere și a atașat rezultatul curl -I; punctul s-a închis fără discuții.

Greșeli frecvente

  • Adaugi headerele în blocul server și le pierzi în location-urile cu add_header propriu.
  • Impui o CSP fără perioadă de Report-Only și blochezi scriptul de plăți sau fonturile.
  • Folosești 'unsafe-inline' și 'unsafe-eval' peste tot și rămâi cu iluzia unei politici.
  • Setezi X-Frame-Options și frame-ancestors cu valori contradictorii; browserele moderne ascultă doar de frame-ancestors.
  • Verifici headerele doar la instalare, nu după fiecare deploy care schimbă nginx.

Cum te ajută 4hosting

  • Hardening & Compliance configurează headerele și CSP în etape, cu verificare după deploy, pe VPS-urile și serverele dedicate 4hosting.
  • Serviciul React / Next.js aplică nonce-uri CSP la nivel de aplicație, ca politica să nu aibă nevoie de 'unsafe-inline'.
  • Orele de CyberSecurity incluse (1–8 lunar la VPS, 10 la dedicate și GPU) acoperă trecerea de la Report-Only la politica impusă; le ceri din panoul de client; orele se consumă în luna calendaristică, fără reportare.
  • WAF & DDoS completează headerele cu reguli OWASP la nivel de server, pentru cererile care nu ajung niciodată în browser.

Întrebări conexe

  • Mai am nevoie de X-XSS-Protection și X-Frame-Options?

    X-XSS-Protection e ignorat de browserele moderne și poate introduce probleme; nu îl seta. X-Frame-Options e înlocuit de frame-ancestors din CSP, dar îl poți păstra cu DENY sau SAMEORIGIN pentru browsere vechi, dacă nu contrazice directiva CSP.

  • Headerele de securitate afectează performanța sau SEO?

    Nu. Sunt câteva sute de octeți pe răspuns și nu influențează indexarea. Singurul efect vizibil apare dacă o CSP prea strictă blochează un script necesar — de aceea trece prin Report-Only. Scanerele publice includ headerele în scor, ceea ce contează la chestionarele clienților.

Cere o verificare de securitate

Acest ghid adună într-un singur loc măsurile care contează pentru un server de producție al unei firme din Moldova: de la cheia SSH până la copia de backup pe care nimeni nu o poate șterge. Fiecare capitol trimite la o pagină de întrebare cu pași, comenzi și exemple. Este scris pentru echipe care livrează clienților din UE, raportează la instituții locale sau vând online și nu își permit o zi de indisponibilitate.

Ghiduri pentru firme din Moldova