FacturareIntră în aplicație
Integrare în aplicația taSecuritate · pagina 9 din 10

Securitate

Ce trece prin browser, ce verificăm și ce faci dacă ceva merge prost.

Actualizat la

Serverul tău semnează cu cheia privată o aserțiune de câteva sute de octeți despre utilizatorul logat. Ea trece prin browser și ajunge la noi, unde o verificăm înainte să scriem ceva în baza de date. Cheia privată nu pleacă de pe server.

Serverul tăusemnează; cheia privată rămâne aici
Pagina tao duce la iframe
Chappao verifică
eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsImp3ayI6.eyJhdWQiOiJodHRwczovL2ZhY3R1cmFyZS5jaGFwcGEucm8i.q3Zk9mVhRSn0bT6kXw1Yc
{ "sub": "user_8842", "aud": "https://facturare.chappa.ro", "exp": "peste 5 min", "ori": "https://app.exemplu.ro", "scope": "documents:read documents:write" }
  1. Semnătura ES256 se potrivește cu cheia publică din antet
  2. E pentru facturare.chappa.ro, nu pentru altcineva
  3. E încă valabilă: trăiește cel mult 15 minute
  4. Nu a mai fost folosită
  5. Vine de pe pagina pentru care a fost semnată

Ce trece prin browser

În modurile cu utilizatorii tăi, aserțiunea trece prin pagina ta: în adresa iframe-ului sau printr-un mesaj. Așa funcționează orice autentificare unică între două site-uri, și nu e o slăbiciune, pentru că aserțiunea nu e o cheie și nu se poate refolosi:

  • Semnată. Orice schimbare, fie și a unui drept din scope, strică semnătura.
  • Scurtă. Trăiește cel mult 15 minute; de obicei o semnezi pentru 2 până la 5.
  • De unică folosință. Al doilea drum cu același jti e refuzat.
  • Pentru noi și pentru pagina ta. E semnată pentru facturare.chappa.ro (aud) și, cu ori, pentru originea paginii tale: iframe-ul o compară cu pagina care îl afișează.

După ce deschide sesiunea, aserțiunea nu mai contează. Sesiunea trăiește în iframe, pe domeniul nostru, ca un token în memorie, nu ca un cookie; scripturile paginii tale nu o pot citi, iar blocarea cookie-urilor terțe nu o încurcă.

Ce verificăm, în ordine

  1. Formatul: JWS compact, algoritmul doar ES256. none, HS256, RS256 sau un antet cu crit sunt refuzate, la fel o cheie care conține partea privată.
  2. Semnătura, cu cheia publică din antet sau cu cea înregistrată pentru kid. Integrarea e identificată de amprenta cheii, nu de ce scrie în aserțiune.
  3. Cheia nu e revocată și integrarea nu e blocată.
  4. Destinatarul (aud), timpul (iat, exp, cu 60 de secunde toleranță de ceas) și jti nefolosit.
  5. Originea paginii, față de ori și de originile permise din portal.
  6. Abia apoi scriem: utilizatorul, firmele, sesiunea.

Dacă ceva merge prost

  • Cineva rulează cod în pagina ta (XSS). Poate lua o aserțiune nefolosită și o poate folosi înaintea paginii, tot din pagina ta. Dar un astfel de cod controlează deja sesiunea utilizatorului în aplicația ta: aserțiunea nu îi dă nimic în plus față de ce poate face utilizatorul.
  • Cineva prinde o aserțiune nefolosită în afara paginii tale. Verificarea originii o oprește într-un iframe de pe alt site; în rest o limitează viața de câteva minute și folosirea unică. De aceea nu le loga.
  • Îți scapă cheia privată. O revoci din portal, iar sesiunile deschise cu ea se închid imediat. Dacă nu ai acces la portal, oricine are cheia o poate revoca (revocarea de urgență).
  • Accesul la ANAF nu vine niciodată dintr-o aserțiune: conexiunea cu SPV cere autorizarea reală a firmei, cu certificatul ei (autorizarea ANAF).

Ce faci tu

  • Cheia privată doar pe server (ideal KMS/HSM sau un secret manager), permisiuni 0600, nu în repository.
  • exp scurt, jti unic, sub din sesiunea ta, niciodată din input.
  • Folosește ori și, în producție, originile permise din portal.
  • Verifică event.origin și event.source la mesajele primite; trimite cu targetOrigin exact.
  • Nu loga aserțiunile; tratează-le ca pe parole cu viață scurtă.
  • Sesiunea din iframe e un token în memoria iframe-ului (fără cookie-uri terțe): funcționează în Safari și cu blocarea cookie-urilor terțe.