Aceasta este o copie de probă. Site-ul adevărat este data-analist.com.
contact@data-analist.com
str. Igor Vieru 15, Chișinău Republica Moldova

Automatizăm procese. Analizăm date. Găsim soluții.

Securitatea datelor în SQL – ce trebuie să eviți obligatoriu
HomeSQL & Databases Securitatea datelor în SQL – ce trebuie să eviți obligatoriu
Securitatea datelor în SQL nu e mai grea decât era acum cinci ani. E doar mai des ratată. O trecere prin greșelile pe care nu și le mai permite nimeni serios.

SQL injection a fost catalogat ca vulnerabilitate critică pentru prima dată în 1998. Au trecut aproape 30 de ani. Continuă să fie pe lista OWASP Top 10 în 2027. Nu pentru că tehnologia nu a evoluat. Pentru că oamenii continuă să facă aceleași greșeli, pe sisteme noi, în limbaje noi, cu framework-uri noi.

Securitatea datelor în SQL nu e o problemă necunoscută. E o problemă disciplinară. Articolul nu îți va arăta lucruri exotice. Îți va arăta ce continuă să facă echipele care apoi apar în știri.

Securitatea datelor: 1. Construcția de query-uri prin concatenare de string-uri

Cea mai veche și cea mai persistentă vulnerabilitate. Codul arată așa:

query = "SELECT * FROM users WHERE email = '" + user_input + "'"

Cu input ' OR '1'='1, query-ul devine SELECT * FROM users WHERE email = '' OR '1'='1'. Atacatorul vede toți utilizatorii.

Soluția există de două decade. Prepared statements. Parametrizare. Orice limbaj modern le oferă nativ. Și totuși, în 2027, în baze de cod proaspete, în startup-uri, în aplicații enterprise — concatenarea apare. Uneori pentru că un dezvoltator junior nu a învățat. Mai des pentru că „era mai simplu așa, ne întoarcem și fixăm”.

Nu se întoarce nimeni. Codul scris azi în grabă va fi în producție în 2030. Aceleași vulnerabilități.

Antidotul în practică nu e doar codul corect. E disciplina de a folosi un ORM sau query builder care face parametrizarea obligatorie. Pentru Python: SQLAlchemy. Pentru Node.js: Prisma sau Knex. Pentru .NET: Entity Framework sau Dapper cu parametri obligatorii. Excepțiile de la regulă (raw SQL) trebuie să fie explicite și revizuite.

2. Permisiuni de cont aplicație egale cu cele de admin

Aplicația web se conectează la baza de date cu user root sau cu un cont care are ALL PRIVILEGES pe toată baza.

Asta e o capcană organizațională, nu tehnică. La început, dezvoltatorul a configurat conexiunea cu drepturi complete „ca să meargă rapid”. Niciodată nu a venit cineva să restrângă. Câteva luni mai târziu, o vulnerabilitate minoră în aplicație se transformă în compromiterea completă a bazei.

Principiul corect e least privilege. Aplicația web are nevoie să citească din 12 tabele și să scrie în 3? Atunci contul ei are exact aceste permisiuni. Nu DROP TABLE. Nu CREATE USER. Nu acces la baza de loguri. Nimic în plus.

Pare evident când îl spui. În practică, în peste jumătate din auditele pe care le văd echipele de securitate, contul aplicației are mai multe permisiuni decât ar trebui. Setupul inițial a rămas. Refactoring-ul de permisiuni nu vine pe nicio listă de priorități pentru că „funcționează deja”.

Devine prioritate brusc după primul incident. Costul minutelor de configurare corectă inițială vs. costul săptămânilor de remediere post-breach nu se compară.

3. Date sensibile stocate fără criptare la nivel de coloană

O bază de date conține parole stocate în clar. Sau date de card. Sau CNP-uri. Sau e-mail-uri într-o aplicație de healthcare.

Storage encryption (TDE – Transparent Data Encryption) la nivel de disc nu rezolvă problema. Protejează doar dacă cineva fură fizic discurile. Protejează zero dacă atacatorul are acces la baza de date prin conexiune normală.

Pentru date cu adevărat sensibile, criptarea trebuie să fie la nivel de aplicație sau la nivel de coloană în baza de date. Parolele se hash-uiesc cu algoritmi moderni (bcrypt, argon2). Datele cu adevărat secrete (chei API, tokeni) se criptează cu chei gestionate într-un KMS extern.

Greșeala clasică: hash-uirea parolelor cu MD5 sau SHA-1. În 2027, ambii algoritmi sunt complet nesiguri pentru hash-uire de parole. Bibliotecile de cracking le pot inversa pe hardware obișnuit. Echipele care moștenesc baze vechi cu hash-uri MD5 trebuie să migreze, nu să le păstreze „pentru că funcționează”.

Iar pentru date care nu pot fi hash-uite (trebuie să rămână recuperabile), criptarea simetrică cu cheie din KMS e standardul. AWS KMS, Azure Key Vault, Google Cloud KMS — toate trei livrează această capacitate la cost rezonabil.

4. Backup-uri fără criptare, accesibile public

Backup-urile bazei stau într-un S3 bucket. Bucket-ul e configurat „cu permisiuni public read” pentru că „era mai simplu pentru când trebuie să descarc de pe alt server”. A trecut un an. Backup-urile sunt încă acolo. Public.

Asta nu e teorie. Sunt zeci de incidente publice anual unde scurgerile de date au venit din backup-uri stocate prost. În 2024, mai multe companii românești au pățit exact acest scenariu. Datele clienților erau criptate în producție. Backup-urile, nu.

Regula non-negociabilă: backup-urile sunt cel puțin la fel de sensibile ca baza originală. Aceeași criptare. Aceleași politici de acces. Aceeași retention. Plus testare periodică de restaurare — backup-urile care nu pot fi restaurate sunt zero.

Detaliu pragmatic: configurarea S3 sau a oricărui storage cloud cu Block Public Access activat la nivel de cont nu costă nimic. Ar trebui să fie default-ul pentru orice cont nou. Și totuși, prima sarcină pe care unii o fac pe un cont nou e să dezactiveze aceste protecții „pentru flexibilitate”.

5. Loguri care înregistrează date sensibile

Aplicația face logger.info("User login attempt with email " + email + " and password " + password). Codul a fost adăugat în prima săptămână de dezvoltare „pentru debugging”. Nu a fost niciodată șters.

Logurile aplicației ajung în sisteme de monitoring care, la rândul lor, au politici de acces mai laxe decât baza de date. Echipa de support are acces. Echipa de DevOps are acces. Furnizorii externi de monitoring (Datadog, New Relic) au copii.

Parolele în loguri sunt cazul evident. Mai subtil: numerele de card, CNP-urile, tokeni de sesiune, header-e Authorization. Toate apar în loguri „accidental” dacă nu există disciplină de filtrare.

Antidotul cere două lucruri. Politici explicite de ce nu se loghează (lista negativă) și middleware care filtrează automat câmpuri sensibile înainte de log. Frameworks moderne au această capacitate integrată; dezvoltatorii trebuie să o activeze și să o testeze.

6. Lipsa rotirii credențialelor și a auditării accesului

Parolele admin pentru baze de producție sunt stabilite la setup. Cinci ani mai târziu, sunt aceleași. Trei foști angajați le mai cunosc. Niciun audit nu a fost făcut.

Sau, varianta modernă: cheile de access la AWS RDS sau Azure SQL sunt în fișiere de configurare commit-uite în Git acum trei ani, într-un repo care a fost între timp făcut public.

Rotirea credențialelor și gestionarea lor prin secret managers (HashiCorp Vault, AWS Secrets Manager, Azure Key Vault) au devenit standard în 2027. Companiile care nu le folosesc operează în mod nesigur, nu pentru că nu există soluții, ci pentru că nu au investit în procese.

În paralel, auditarea accesului — cine s-a conectat când, de unde, ce query-uri a rulat — e o capacitate nativă în majoritatea bazelor moderne. PostgreSQL audit logs, MySQL audit plugin, SQL Server Audit. Activarea costă efort minim. Nu o activează decât echipele care au pățit cel puțin un incident.

7. Asumpția că rețeaua internă e sigură

„Baza nu e expusă la internet, deci e sigură”. Era o presupunere rezonabilă în 2005. În 2027, e o capcană.

Atacatorii moderni compromit baze prin rețeaua internă, după ce au câștigat acces la un workstation prin phishing sau printr-o aplicație web vulnerabilă. Odată în rețea, baza care nu cere autentificare puternică sau care permite conexiuni din orice IP intern e deschisă.

Zero Trust e un termen comercial supraîncărcat, dar principiul de bază e simplu: niciun acces nu se presupune sigur doar pentru că vine „din interior”. Fiecare conexiune se autentifică, se autorizează, se loghează.

În practică, asta înseamnă: TLS pentru toate conexiunile (chiar și interne), liste de IP-uri permise pentru bazele de date, autentificare mutuală cu certificate pentru aplicații critice. Costul implementării e mediu. Beneficiul devine vizibil când investigatorii post-breach încep să întrebe „de ce am putut accesa baza de pe orice mașină din rețeaua corporativă?”.

8. Migrările care nu sunt verificate pentru leak-uri

Echipa migrează datele dintr-o bază veche într-una nouă. Procesul durează săptămâni. Datele sensibile trec printr-un mediu intermediar — un server temporar, un S3 bucket, un export local pe laptop-ul dezvoltatorului care face migrarea.

Migrarea reușește. Datele sunt în baza nouă, securizată corect. Dar rămâne copia veche pe mediul intermediar. Uneori timp de ani. Uneori uitată complet.

Procesul corect de migrare include o etapă explicită de cleanup: ștergerea fișierelor intermediare, verificarea că nu există copii remanente, ștergerea credențialelor temporare folosite. Acest pas e cel mai des sărit pentru că „migrarea s-a terminat, mergem mai departe”.

Audit recent al unei echipe de retail mid-market român a descoperit, la 18 luni după o migrare, un fișier dump SQL de 4 GB pe un share intern. Conținea tabela de utilizatori cu hash-uri MD5 vechi. A fost ștearsă imediat. Cât timp a stat acolo, cine a accesat-o — imposibil de verificat retrospectiv.

Lista de evitări obligatorii, condensată

  • Concatenare de string-uri pentru construcția query-urilor.
  • Cont aplicație cu privilegii admin.
  • Parole stocate cu hash-uri vechi (MD5, SHA-1, sau plain text).
  • Date sensibile fără criptare la nivel de aplicație.
  • Backup-uri stocate fără criptare sau cu acces public.
  • Loguri care includ parole, tokeni sau date personale.
  • Credențiale care nu se rotesc niciodată.
  • Lipsă completă de audit pe accesul la baze.
  • Asumpția că rețeaua internă protejează automat.
  • Migrări fără cleanup explicit al mediilor intermediare.

Zece elemente. Niciunul exotic. Toate evitabile cu disciplină.

Tema se leagă natural de discuția despre optimizare query, unde am intrat în detaliu pe pattern-urile pe care le observăm în piață. Pentru actualizări și detalii suplimentare, PostgreSQL Docs rămâne sursa principală pe acest subiect. În fond, securitate SQL nu e doar un concept tehnic — este o decizie de business cu impact direct pe productivitatea echipei.

Ce face cu adevărat diferența

Echipele care nu apar în știri pentru breach-uri nu au tool-uri magice. Au procese banale aplicate consistent.

Review-uri de cod cu listă specifică de checks de securitate. Un PR care introduce un query SQL primește întrebarea „e parametrizat?” obligatoriu, nu opțional.

Audit periodic al permisiunilor de cont. La fiecare 3-6 luni, cineva trece prin lista de conturi de baze și verifică dacă cineva are mai multe drepturi decât are nevoie. Greutatea procesului ține o oră, costul evitării — incalculabil.

Penetration testing extern, măcar anual. O echipă externă încearcă să spargă sistemele tale. Ce găsește ea, ai prefera să găsești înainte ca atacatorii reali să o facă. Costul: $5.000-$30.000 pentru o companie mid-market. ROI evident.

Training de bază pentru toți dezvoltatorii, nu doar pentru cei „de securitate”. Greșelile de mai sus nu vin din lipsa specialiștilor în securitate. Vin din lipsa cunoștințelor de bază răspândite în întreaga echipă de dezvoltare.

Plan de răspuns la incident scris înainte de incident. Cine sună pe cine la 3 dimineața când vine alerta? Cine vorbește cu presa? Cine notifică autoritatea de date personale? Răspunsurile improvizate în panică sunt răspunsuri costisitoare.

Niciun element din lista de mai sus nu e revoluționar. Sunt practici cunoscute, scrise în standarde, predate în cursuri. Diferența între echipele care le aplică și cele care nu le aplică se vede direct în statistica incidentelor. Securitatea datelor în SQL nu cere genialitate. Cere consecvență. Care, după 30 de ani de SQL injection în top 10, pare să fie deficitul cronic al industriei.

În practică, securitate SQL a trecut de la subiect de roadmap la prioritate operațională pentru echipele care livrează rezultate de business — exact tipul de tracțiune pe care o vedem reflectată în deciziile reale de buget. Pentru cititorii care lucrează zilnic cu securitate SQL, articolul rămâne deschis pentru update-uri pe măsură ce piața evoluează.


Întrebări frecvente

Care e cea mai persistentă vulnerabilitate SQL?

Construcția query-urilor prin concatenare de string-uri. Un query de forma „SELECT * FROM users WHERE email = ‘” + user_input + „‘” devine, cu inputul ‘ OR ‘1’=’1, un query care returnează tot tabelul. Soluția — interogările parametrizate — există de două decenii.

De ce nu e suficientă criptarea la nivel de disc?

Pentru că Transparent Data Encryption protejează doar discul, nu accesul la date. Pentru date cu adevărat sensibile, criptarea trebuie făcută la nivel de aplicație sau de coloană. Greșeala clasică rămâne hash-uirea parolelor cu MD5 sau SHA-1, iar pentru datele care trebuie să rămână recuperabile standardul e criptarea simetrică cu cheie dintr-un KMS.

Ce se uită cel mai des la backup-uri?

Că sunt cel puțin la fel de sensibile ca baza originală. Un backup într-un bucket S3 fără criptare și fără acces restricționat anulează toate celelalte măsuri. Activarea Block Public Access la nivel de cont nu costă nimic.

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *

Politica de confidențialitate · Politica de cookie-uri