Straturile de protecție ale platformei, de la izolarea firmelor în baza de date până la jurnalele care nu scriu niciodată un secret.
Pe scurt
| Strat | Ce face |
|---|---|
| Izolarea firmelor | Row Level Security FORCE pe fiecare tabel cu firma_id |
| Acces declarat | fiecare rută își declară accesul; ruta nedeclarată răspunde 401 ruta_nedeclarata |
| Sesiune | cookie __Host-sesiune, HttpOnly, Secure, SameSite=Lax |
| Gardă CSRF | scrierile cu cookie venite de pe alt site sunt refuzate cu 403 |
| Încadrare | frame-ancestors 'self' și X-Frame-Options: SAMEORIGIN pe orice răspuns |
| Parole | scrypt cu sare per cont, liste de parole comune refuzate, ultimele 5 parole nu se pot refolosi |
| Limite | 300 de scrieri pe minut pe sesiune, 1200 pe IP (vezi Limite) |
| Jurnale | cookie-ul, antetul Authorization și orice câmp secret sunt înlocuite cu [ascuns] |
Izolarea firmelor
Fiecare cerere fixează firma activă în conexiunea la baza de date (app.firma_id). Politicile RLS sunt în mod FORCE, deci se aplică și proprietarului tabelului. O greșeală într-o interogare nu poate întoarce rândurile altei firme: baza de date pur și simplu nu le arată.
Tabelele cele mai sensibile (hash-urile parolelor vechi, sărurile) nu pot fi citite nici de utilizatorul bazei de date al aplicației. Verificarea se face prin funcții SQL care întorc doar „da” sau „nu”.
Garda CSRF
Cookie-ul este SameSite=Lax, ca un link dintr-un email să te ducă direct în aplicație. Pentru scrieri există o gardă separată, aplicată înainte de orice rută:
Sec-Fetch-Site: cross-site → 403
fără Sec-Fetch-Site, cu Origin ≠ aplicația → 403
fără cookie (aplicații, scripturi, MCP) → trece; se aplică autentificarea ruteiParolele
- Hash
scrypt, cu sare per cont; parola în clar nu se scrie nicăieri. - Parolele din listele publice de parole sparte sunt refuzate la alegere.
- Parola nouă nu poate fi una dintre ultimele 5 ale contului.
- După a treia parolă greșită pe un cont real, proprietarul primește o alertă.
- Resetarea de către administrator închide toate sesiunile, acordurile OAuth și codurile de email ale contului.
Antetele de securitate
Content-Security-Policy: frame-ancestors 'self'
X-Frame-Options: SAMEORIGINO rută care își pune propriul Content-Security-Policy îl păstrează.
Jurnalele
Jurnalele serverului ascund mereu, fără excepție configurabilă:
- antetul
Cookieși antetulAuthorization; - orice câmp numit
secret, până la trei niveluri adâncime în obiect (secret,x.secret,x.y.secret) și în corpul cererii; - codul de invitație din cale (
/v1/invitatii/[cod]).
Raportarea unei probleme
Dacă găsești o vulnerabilitate, scrie administratorului platformei înainte de orice publicare. Nu testa pe datele altor firme.