SQL-injektio
SQL-injektio on ollut jokaisen verkkoturvallisuuden haavoittuvuusluettelon kärjessä tai lähellä sitä 1990-luvun lopulta lähtien. Korjaus – parametroidut kyselyt – on tunnettu, yksinkertainen ja sitä on suositeltu kahden vuosikymmenen ajan. Silti uusia SQLi-haavoittuvuuksia löydetään joka viikko. Luokka säilyy, koska vikatila on hienovarainen ja monien kehysten oletusasetukset ovat epätäydellisiä.
Artikkelin koko runko on englanniksi alla.
SQL-injektio (SQLi) on haavoittuvuusluokka, jossa hyökkääjä voi syöttää SQL-koodia kyselyyn, jonka sovellus lähettää tietokantaansa. Jos hyökkääjä onnistuu, hän voi lukea, muokata tai poistaa tietoja, joihin hänellä ei ole valtuuksia, joskus suorittaa koodia tietokantapalvelimessa ja joskus kääntyä hyökkäyksiin itse sovellusta vastaan.
Klassinen virhe
Oppikirjaesimerkki. Sovellus hyväksyy käyttäjätunnuksen kirjautumislomakkeesta ja etsii sen:
query = "SELECT * FROM users WHERE username='" + input + "';"If input on alice, thequeryX tulee:
SELECT * FROM käyttäjiltä WHERE username='alice';Normaali. Mutta jos input on alice' TAI '1'='1, kyselystä tulee:
SELECT * FROM users WHERE username='alice' OR '1'='PLZ'PLZ3TheXXLZ3TheXXLZ33XPLX3 '1'='1'on aina totta. Kysely palauttaa kaikki taulukon käyttäjät. Kehittyneemmillä hyötykuormilla hyökkääjä voi tyhjentää taulukoita, muokata tietueita tai eskaloida edelleen.Hyökkäyskategoriat
- Klassinen / kaistan sisäinen SQLi. Lisätyn kyselyn tulokset näkyvät sovelluksessa. Hyökkääjä lukee tiedot suoraan.
- Blind SQLi. Vastauksessa ei näy tietoja, mutta sovelluksen käyttäytyminen muuttuu sen mukaan, palauttaako lisätty kysely arvon tosi vai epätosi. Hyökkääjä poimii tiedot bitti kerrallaan esittämällä kysymyksiä, kuten "onko järjestelmänvalvojan salasanan ensimmäinen merkki 'a"?"
- Aikapohjainen sokea SQLi. Hyökkääjä käyttää
SLEEP()tai vastaavaa, jotta tietokanta vastaa hitaasti, kun ehto on tosi. Jopa hitaampi tietojen suodattaminen, mutta toimii, kun sovellus ei anna vastauspalautetta. - Kaistan ulkopuolinen SQLi. Hyökkääjä huijaa tietokannan muodostamaan ulkoisen verkkoyhteyden (DNS-haku, HTTP-pyyntö), joka vuotaa tietoja hallitsemaansa palvelimeen.
- XiPLZ- tai5SQLXcon5SQLX. haitallinen syöttö tallennetaan ensin tietokantaan, sitten luetaan ja käytetään toisessa kyselyssä epäturvallisesti. Lisäys tapahtuu eri kontekstissa kuin syöte.
Korjaus: parametrisoidut kyselyt
Oikea tapa tehdä kysely tietokannasta käyttäjän syötteellä on käyttää parametrien paikkamerkkejä, ei koskaan ketjuttaa merkkijonoja. Käytännössä kaikilla kielillä:
// Python (psycopg2)
cursor.execute("SELECT * FROM käyttäjiltä WHERE käyttäjätunnus=%s", (syöttö,))
// Java
stmt = conn.prepareStatement("SELECT * FROM käyttäjät WHERE käyttäjätunnus=?");
stmt.setString(1, input);
// JavaScript (pg)
client.query("SELECT * FROM users WHERE username=$1", [input]);Ajuri lähettää SQL:n ja parametriarvot erikseen. Tietokanta ei koskaan sekoita syöttötietoja SQL-syntaksiin. Vaikka syöte sisältää lainausmerkkejä, puolipisteitä, OR-lauseita tai mitä tahansa muuta SQL-syntaksia, sitä käsitellään datana.
Tämä toimii. Se on ollut suositeltu lähestymistapa kahden vuosikymmenen ajan. Haasteena ei ole tekniikka; se varmistaa, että jokainen koodikannan kysely käyttää sitä.
ORM:t eivät ole automaattisesti turvallisia
Objektirelaatiokartoittajat (ActiveRecord, Sequelize, Hibernate, SQLAlchemy) käyttävät oletusarvoisesti parametroituja kyselyitä, mikä on hienoa. Mutta jokaisessa ORM:ssa on hätäluukut:
raw()-menetelmät, jotka ottavat mielivaltaisia SQL-merkkijonoja- Merkkijonopohjaisia ORDER BY -lauseita (sarakkeiden nimiä ei voi parametroida) XT interpoloitavissa nimiksi PLZ85X queries
- Tallennetut proseduurit, jotka itse ketjuttavat
Nykyaikaiset SQLi-virheet näkyvät tyypillisesti näissä reunatapauksissa, ei pääasiallisessa CRUD-koodipolussa.
NoSQL-injektio
SQL:n malli ei ole. MongoDB, Redis, ElasticSearch, GraphQL – mikä tahansa kyselykieli, joka hyväksyy strukturoidun syötteen käyttäjiltä, voi olla ruiskeena, jos syöttöä ei ole vahvistettu. MongoDB:n $ne-, $gt-, $regex-operaattorit ovat yleisiä injektiovektoreita, kun JSON-hyötykuormia ei tarkasteta tiukasti skeeman mukaan. kyselyt:
- Vähimmän oikeudet omaavat tietokantatilit. Sovelluksen tulee muodostaa yhteys käyttäjään, jolla on vain sen tarvitsemat käyttöoikeudet. Vain luku -polut käyttävät vain luku -oikeuksia. Rajoittaa vahinkoa, kun SQLi:tä käytetään hyväksi.
- ISyötteen validointi. Rajoita syötteet odotettuihin muotoihin. Hyödyllinen, mutta ei yksinään riittävä.
- Web Application Firewalls (WAFs). Pattern-match ilmeiset SQLi-yritykset. Ohitettavissa, mutta hitaat hyökkääjät alas.
- Staattinen analyysi. Työkalut, jotka tarkistavat merkkijonoketjutettujen kyselyjen lähteen. Nykyaikaiset IDE:t merkitsevät nämä.
- Database hardening. Poista käytöstä tarpeettomat ominaisuudet (
xp_cmdshellMSSQL:ssä, vaaralliset laajennukset PostgreSQL:ssä).
FamousSQL tapaukset
- 2007 TJX — 94 miljoonaa luottokorttia. Alkoi Wi-Fi-kompromissilla, mutta SQLiä käytettiin suodattamiseen sisäisistä tietokannoista.
- 2008 Heartland — 130 miljoonaa korttitietuetta. SQLi antoi ensimmäisen pääsyn verkkoon.
- 2012 LinkedIn — 117 miljoonaa salasanatiivistettä suodatettiin SQLin kautta.
- 2017 Equifax — Apache Strutsin tieto oli osa SQL-post-com-haavoittuvuutta. exfiltration.
- Kai 2020s — lukemattomia pienempiä tietomurtoja SaaS-yrityksissä, verkkokauppasivustoissa, valtion virastoissa.
Luokka on vuosikymmeniä vanha ja edelleen hyvin elossa.
Usein kysytyt kysymykset
- Onko SQL-injektio edelleen yleistä?
- Kyllä. OWASP:n Top 10 listaa Injectionin (johon sisältyy SQLi) joka vuosi kolmen parhaan kategoriansa joukkoon. Virhepalkkio-ohjelmat näkevät SQLi-raportteja joka viikko. Nykyaikaiset puitteet ovat vähentäneet sen taajuutta pääkoodipoluilla, mutta vanhat sovellukset, reunatapaukset ja ORM-pakoluukut pitävät luokan hengissä.
- Voiko verkkosovellusten palomuuri pysäyttää kaiken SQL-lisäyksen?
- Ei. WAF:t havaitsevat ilmeiset kuviot ja pysäyttävät vaatimattomat hyökkääjät, mutta asiantuntevat hyökkääjät voivat luoda ohituksia – erilaisia koodauksia, kommenttien lisäystä, vaihtoehtoista SQL-syntaksia. WAF:t ovat hyödyllinen kerros; ne eivät korvaa turvallista kyselyrakennetta sovelluksessa.
- Estääkö HTTPS SQL-injektion?
- Ei. SQLi on sovellustason haavoittuvuus. HTTPS suojaa siirrettävät tiedot, mutta ei vahvista sisältöä. Hyökkääjän haitallinen syöte saapuu HTTPS:n kautta aivan kuten kaikkien muidenkin; sovellus on se, joka käsittelee tai ei käsittele sitä turvallisesti.
- Ovatko NoSQL-tietokannat immuuneja?
- Ei. NoSQL-injektio on oma luokkansa. MongoDB, Elasticsearch ja muut hyväksyvät strukturoidun kyselyn syötteen, jota voidaan muokata, jos sitä ei ole tarkasti vahvistettu. Suojausmallit ovat samanlaisia (käsittele käyttäjän syötettä datana, ei koskaan kyselyrakenteena), mutta tietyt hyökkäykset vaihtelevat.
- Kuinka testaan omaa sivustoani SQL-injektion varalta?
- Työkalut, kuten sqlmap, automatisoivat yleisten SQLi-mallien testauksen; OWASP ZAP ja Burp Suite sisältävät skannerit. Kehittäjille luotettavin tarkistus on koodin tarkistus ja staattinen analyysi merkkijonoihin ketjutetuille kyselyille. Läpäisevyystestaukseen sisältyy erityisesti SQLi-arviointi.