SQL injekcija
SQL injection je bio na ili blizu vrha svih popisa sigurnosnih ranjivosti na webu od kasnih 1990-ih. Popravak - parametrizirani upiti - poznat je, jednostavan i preporučuje se već dva desetljeća. Ipak, svaki tjedan otkrivaju se nove SQLi ranjivosti. Kategorija i dalje postoji jer je način kvara suptilan, a zadane postavke mnogih okvira nesavršene.
Cjeloviti članak nalazi se u nastavku na engleskom jeziku.
SQL injekcija (SQLi) je klasa ranjivosti u kojoj napadač može ubaciti SQL kod u upit koji aplikacija šalje svojoj bazi podataka. Ako uspije, napadač može čitati, modificirati ili brisati podatke za pristup kojima nema ovlaštenje, ponekad izvršiti kod na poslužitelju baze podataka, a ponekad prijeći na napade na samu aplikaciju.
Klasična pogreška
Primjer iz udžbenika. Aplikacija prihvaća korisničko ime iz obrasca za prijavu i traži ga:
query = "SELECT * FROM users WHERE username='" + input + "';"Iif input je alice, upit postaje:
SELECT * FROM korisnika WHERE korisničko ime='alice';Normalno. Ali ako je input alice' ILI '1'='1, upit postaje:
SELECT * FROM users WHERE korisničko ime='alice' OR '1'='1';OR '1'='1' je uvijek istina. Upit vraća svakog korisnika u tablici. Sa sofisticiranijim korisnim opterećenjem napadač može izbaciti tablice, modificirati zapise ili dalje eskalirati.
Kategorije napada
- Klasični / unutarpojasni SQLi. Rezultati umetnutog upita pojavljuju se u odgovoru aplikacije. Napadač izravno čita podatke.
- Slijepi SQLi. Nema podataka koji se pojavljuju u odgovoru, ali se ponašanje aplikacije mijenja ovisno o tome vraća li ubačeni upit true ili false. Napadač izvlači podatke jedan po bit postavljajući pitanja poput "je li prvi znak administratorske lozinke 'a'?"
- Time-based blind SQLi. Napadač koristi
SLEEP()ili ekvivalent kako bi baza podataka sporo reagirala kada je uvjet istinit. Još sporija ekstrakcija podataka, ali radi kada aplikacija ne daje povratnu informaciju. - Izvanpojasni SQLi. Napadač prevari bazu podataka da uspostavi vanjsku mrežnu vezu (DNS pretraživanje, HTTP zahtjev) koja curi podatke na poslužitelj koji kontrolira.
- SQLi drugog reda. zlonamjerni unos se prvo pohranjuje u bazu podataka, zatim se kasnije čita i koristi u drugom upitu na nesiguran način. Ubacivanje se događa u kontekstu različitom od ulaza.
Popravak: parametrizirani upiti
Ispravan način postavljanja upita bazi podataka s korisničkim unosom je korištenje rezerviranih mjesta parametara, a nikada spajanje nizova. U osnovi u svakom jeziku:
// Python (psycopg2)
cursor.execute("SELECT * FROM users WHERE korisničko ime=%s", (unos,))
// Java
stmt = conn.prepareStatement("SELECT * FROM korisnici WHERE korisničko ime=?");
stmt.setString(1, unos);
// JavaScript (pg)
client.query("SELECT * FROM users WHERE username=$1", [ulaz]);Upravljački program zasebno šalje SQL i vrijednosti parametara. Baza podataka nikada ne brka ulazne podatke sa SQL sintaksom. Čak i ako unos sadrži navodnike, točku-zarez, klauzule OR ili bilo koju drugu SQL sintaksu, tretira se kao podatak.
Ovo radi. To je bio preporučeni pristup dva desetljeća. Izazov nije tehnika; osigurava da ga koristi svaki upit u bazi koda.
ORM-ovi nisu automatski sigurni
Object-Relational Mappers (ActiveRecord, Sequelize, Hibernate, SQLAlchemy) prema zadanim postavkama koriste parametrizirane upite, što je sjajno. Ali svaki ORM ima izlazne otvore:
raw()metode koje uzimaju proizvoljne SQL nizove- Stringove ORDER BY klauzule (imena stupaca ne mogu se parametrizirati)
- Imena tablica interpolirana u upiti
- Pohranjene procedure koje se same spajaju
Moderni SQLi bugovi obično se pojavljuju u ovim rubnim slučajevima, a ne u glavnoj putanji CRUD koda.
NoSQL injekcija
Uzorak nije jedinstven za SQL. MongoDB, Redis, ElasticSearch, GraphQL — bilo koji jezik upita koji prihvaća strukturirani unos od korisnika može se ubaciti ako unos nije potvrđen. MongoDB-ovi operatori $ne, $gt, $regex uobičajeni su vektori ubrizgavanja kada JSON korisni učinci nisu striktno provjeravani shemom.
Dubljinska obrana
Beyond parametrizirani upiti:
- Računi baze podataka s najmanjim privilegijama. Aplikacija bi se trebala povezati s korisnikom koji ima samo dopuštenja koja su mu potrebna. Putovi samo za čitanje koriste vjerodajnice samo za čitanje. Ograničava štetu kada se iskorištava SQLi.
- IProvjera valjanosti unosa. Ograniči unose na očekivane formate. Korisno, ali ne i dovoljno samo po sebi.
- Vatrozidi web-aplikacije (WAF-ovi). Očigledni pokušaji podudaranja uzorka SQLi. Zaobilazni, ali spori napadači.
- Statička analiza. Alati koji skeniraju izvor tražeći upite povezane nizovima. Moderni IDE označavaju ovo.
- Ojačavanje baze podataka. Onemogući nepotrebne značajke (
xp_cmdshellu MSSQL-u, opasna proširenja u PostgreSQL-u).
Poznati SQLi incidenti
- 2007 TJX — 94 milijuna kreditnih kartica. Započelo je s Wi-Fi kompromisom, ali SQLi je korišten za izlazak iz internih baza podataka.
- 2008 Heartland — 130 milijuna kartičnih zapisa. SQLi je dao inicijalni pristup mreži.
- 2012 LinkedIn — 117 milijuna hashova zaporki eksfiltriranih putem SQLi.
- 2017 Equifax — Ranjivost Apache Strutsa, ali SQLi je bio dio podataka nakon kompromitacije exfiltration.
- Tijekom 2020-ih — bezbroj manjih provala u SaaS tvrtkama, stranicama za e-trgovinu, vladinim agencijama.
Kategorija je desetljećima stara i još uvijek vrlo živa.
Često postavljana pitanja
- Je li SQL ubrizgavanje još uvijek uobičajeno?
- Da. OWASP-ov Top 10 navodi Injection (što uključuje SQLi) u svoje tri najbolje kategorije svake godine. Programi za dodjelu grešaka svaki tjedan vide SQLi izvješća. Moderni okviri smanjili su njegovu učestalost u glavnim putovima koda, ali naslijeđene aplikacije, rubni slučajevi i ORM otvori za izlaz održavaju kategoriju na životu.
- Može li vatrozid web-aplikacije zaustaviti sve SQL injekcije?
- Ne. WAF-ovi hvataju očite uzorke i zaustavljaju nesofisticirane napadače, ali iskusni napadači mogu izraditi zaobilaznice - različita kodiranja, umetanje komentara, alternativna SQL sintaksa. WAF-ovi su koristan sloj; oni nisu zamjena za sigurnu konstrukciju upita u aplikaciji.
- Sprečava li HTTPS ubacivanje SQL-a?
- Ne. SQLi je ranjivost aplikacijskog sloja. HTTPS štiti podatke u prijenosu, ali ne potvrđuje sadržaj. Napadačev zlonamjerni unos stiže putem HTTPS-a baš kao i svaki drugi; aplikacija je ono što to čini ili ne obrađuje sigurno.
- Jesu li NoSQL baze podataka imune?
- Ne. NoSQL ubrizgavanje je posebna kategorija. MongoDB, Elasticsearch i drugi prihvaćaju strukturirani unos upita kojim se može manipulirati ako nije strogo provjeren. Zaštitni obrasci su slični (tretirajte korisnički unos kao podatke, nikad kao strukturu upita), ali se specifični napadi razlikuju.
- Kako mogu testirati vlastitu stranicu za SQL injekciju?
- Alati poput sqlmapa automatiziraju testiranje uobičajenih SQLi uzoraka; OWASP ZAP i Burp Suite uključuju skenere. Za programere, najpouzdanija provjera je pregled koda i statička analiza za upite spojene nizovima. Angažmani penetracijskog testiranja posebno uključuju SQLi procjenu.