Python Academy · Oppitunti

Parametrisoidut kyselyt

Estä SQL-injektio

Oppitunti 3/413 vaihetta

Parametrisoidut kyselyt on ilmainen Python Academy-oppitunti CoddyKitissä. Tämä on oppitunti 3/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Python Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Python Academy-kurssilla on yhteensä 4 oppituntia.

Merkkijonojen rakentamisen vaarat

SQL:n rakentaminen merkkijonoja yhdistämällä on riskialtista. Jos käyttäjän syöte sisältää SQL:ää, se voi muuttaa kyselyä. Tätä kutsutaan SQL-injektioksi.

Älkää koskaan tehkö näin epäluotettavien tietojen kanssa.

name = 'Alice'
# Unsafe pattern - do NOT do this
query = "SELECT * FROM users WHERE name = '" + name + "'"
print(query)

Miltä injektio näyttää

Kuvitelkaa haitallinen arvo. Sen yhdistäminen merkkijonoon muuttaa kyselyn merkityksen kokonaan.

name = "x' OR '1'='1"
query = "SELECT * FROM users WHERE name = '" + name + "'"
print(query)
print('The OR clause makes every row match!')

Paikanvaraajat apuun

Turvallinen tapa on käyttää parametrisoituja kyselyitä. Käyttäkää paikanvaraajana merkkiä ? ja välittäkää arvot tuplena. Ajuri käsittelee arvot turvallisesti.

import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)')
cur.execute('INSERT INTO users (name) VALUES (?)', ('Alice',))
cur.execute('SELECT * FROM users')
print(cur.fetchall())
conn.close()

Useita paikanvaraajia

Käyttäkää yhtä ?-merkkiä jokaista arvoa kohden. Välittäkää arvot tuplena samassa järjestyksessä kuin paikanvaraajat esiintyvät.

import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)')
cur.execute('INSERT INTO users (name, age) VALUES (?, ?)', ('Bob', 25))
cur.execute('SELECT * FROM users')
print(cur.fetchall())
conn.close()

Yhden arvon tuplet

Yhden alkion tuple tarvitsee loppuun pilkun: ('Alice',). Ilman pilkkua Python tulkitsee sulkeet pelkäksi ryhmittelyksi.

good = ('Alice',)
bad = ('Alice')
print(type(good), type(bad))

Injektioyritys estetty

Paikanvaraajia käytettäessä haitallinen arvo käsitellään tavallisena tietona, ei SQL:nä. Se ei yksinkertaisesti vastaa mitään.

import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)')
cur.execute('INSERT INTO users (name) VALUES (?)', ('Alice',))
evil = "x' OR '1'='1"
cur.execute('SELECT * FROM users WHERE name = ?', (evil,))
print('Rows matched:', cur.fetchall())
conn.close()

Nimetyt paikanvaraajat

SQLite tukee myös nimettyjä paikanvaraajia syntaksilla :name. Välittäkää arvoista muodostettu sanakirja.

import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)')
cur.execute('INSERT INTO users (name, age) VALUES (:n, :a)', {'n': 'Carol', 'a': 40})
cur.execute('SELECT * FROM users')
print(cur.fetchall())
conn.close()

Parametrit WHERE-lauseessa

Paikanvaraajia voi käyttää kaikissa lausekkeissa, jotka ottavat vastaan arvon, myös WHERE-lauseessa.

import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)')
cur.execute('INSERT INTO users (name, age) VALUES (?, ?)', ('Alice', 30))
cur.execute('INSERT INTO users (name, age) VALUES (?, ?)', ('Bob', 25))
cur.execute('SELECT name FROM users WHERE age > ?', (28,))
print(cur.fetchall())
conn.close()

executemany

Kun haluatte lisätä useita rivejä, käyttäkää funktiota executemany() tupleista koostuvan listan kanssa. Se on nopeampi ja edelleen turvallinen.

import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)')
rows = [('Alice',), ('Bob',), ('Carol',)]
cur.executemany('INSERT INTO users (name) VALUES (?)', rows)
cur.execute('SELECT COUNT(*) FROM users')
print(cur.fetchone())
conn.close()

Paikanvaraajat eivät sovi tunnisteille

Paikanvaraajat toimivat vain arvoille, eivät taulujen tai sarakkeiden nimille. Nimien on oltava peräisin oman koodinne luotetusta sallittujen arvojen luettelosta.

import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)')
allowed = {'name', 'id'}
col = 'name'
if col in allowed:
    cur.execute('SELECT ' + col + ' FROM users')
    print('Safe column query ran')
conn.close()

Uudelleenkäytettävä lisäysfunktio

Kun parametrisoidut lisäykset kääritään funktioon, koodinne pysyy siistinä ja turvallisuus säilyy johdonmukaisesti.

import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)')

def add_user(cursor, name):
    cursor.execute('INSERT INTO users (name) VALUES (?)', (name,))

add_user(cur, 'Dave')
cur.execute('SELECT * FROM users')
print(cur.fetchall())
conn.close()

Pikatesti

Testatkaa turvallisia kyselyitä koskevaa osaamistanne.

Kertaus

Olette oppineet kirjoittamaan injektioilta suojattuja kyselyitä.

  • Älkää koskaan yhdistäkö epäluotettavaa syötettä suoraan SQL:ään
  • Käyttäkää ?-paikanvaraajia arvoista koostuvan tuplen kanssa
  • Nimetyt :name-paikanvaraajat käyttävät sanakirjaa
  • executemany() lisää useita rivejä turvallisesti
  • Paikanvaraajat on tarkoitettu arvoille, eivät tunnisteille
Aloita maksutta

Opi Python tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
76
Oppitunnit
320

Usein kysytyt kysymykset

Onko oppitunti ”Parametrisoidut kyselyt” ilmainen?

Kyllä – oppitunnin ”Parametrisoidut kyselyt” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Python Academy-kurssin, päivitä CoddyKit PROhon. Python Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Parametrisoidut kyselyt”?

Estä SQL-injektio Harjoittelet Python Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Python Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Python Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 3/4.

Kuinka kauan ”Parametrisoidut kyselyt”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Python Academy-oppitunnilla?

Kyllä. Jokainen Python Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Yhteyden muodostaminen ja taulukoiden luominen
  2. Insert, Select, Update, Delete
  3. Parametrisoidut kyselyt
  4. Transaktiot ja kontekstinhallinta
← Takaisin: Python Academy