0Pricing
Python Academy · Lekcja

Zapytania parametryzowane

Zapobiegaj wstrzykiwaniu SQL

Zapytania parametryzowane to bezpłatna lekcja Python Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Python Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Python Academy zawiera 4 lekcji w sumie.

Niebezpieczeństwo składania zapytań z użyciem ciągów znaków

Budowanie zapytań SQL przez łączenie ciągów znaków jest ryzykowne. Jeśli dane wejściowe użytkownika zawierają kod SQL, mogą zmienić zapytanie. Nazywa się to SQL injection.

Nigdy nie rób tego z niezaufanymi danymi.

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

Jak wygląda próba wstrzyknięcia kodu

Wyobraź sobie złośliwą wartość. Połączenie jej z zapytaniem całkowicie zmienia jego znaczenie.

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

Bezpieczne rozwiązanie: parametry zastępcze

Bezpiecznym rozwiązaniem są zapytania parametryzowane. Użyj ? jako parametru zastępczego i przekaż wartości w krotce. Sterownik bezpiecznie je zabezpieczy.

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()

Wiele parametrów zastępczych

Użyj jednego ? dla każdej wartości. Przekaż je w krotce w tej samej kolejności, w której występują w zapytaniu.

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()

Krotki jednoelementowe

Krotka jednoelementowa wymaga przecinka na końcu: ('Alice',). Bez niego Python potraktuje nawiasy jedynie jako grupowanie.

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

Zablokowana próba wstrzyknięcia kodu

W przypadku parametrów zastępczych złośliwa wartość jest traktowana jak zwykłe dane, a nie jak kod SQL. Po prostu nie dopasuje żadnego wiersza.

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()

Nazwane parametry zastępcze

SQLite obsługuje także nazwane parametry zastępcze w składni :name. Przekaż słownik wartości.

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()

Parametry w WHERE

Parametry zastępcze działają w każdej klauzuli przyjmującej wartość, w tym w WHERE.

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

Aby wstawić wiele wierszy, użyj executemany() z listą krotek. Jest to szybsze i nadal bezpieczne.

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()

Parametry zastępcze nie służą do identyfikatorów

Parametry zastępcze działają tylko dla wartości, a nie dla nazw tabel ani kolumn. Nazwy te muszą pochodzić z zaufanej listy dozwolonych wartości zapisanej w Twoim kodzie.

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()

Wielokrotnego użytku funkcja wstawiająca

Umieszczenie parametryzowanych operacji wstawiania w funkcji pomaga zachować przejrzystość kodu i zapewnia jego stałe bezpieczeństwo.

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()

Szybki test

Sprawdź swoją wiedzę o bezpiecznych zapytaniach.

Podsumowanie

Nauczyłeś się pisać zapytania odporne na SQL injection.

  • Nigdy nie łącz niezaufanych danych wejściowych z kodem SQL
  • Używaj parametrów zastępczych ? wraz z krotką wartości
  • Nazwane parametry zastępcze :name przyjmują słownik
  • executemany() bezpiecznie wstawia wiele wierszy
  • Parametry zastępcze służą do wartości, a nie do identyfikatorów

Często zadawane pytania

Czy lekcja „Zapytania parametryzowane” jest bezpłatna?

Tak — pełny tekst „Zapytania parametryzowane” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Python Academy, przejdź na CoddyKit PRO. Kurs Python Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Zapytania parametryzowane”?

Zapobiegaj wstrzykiwaniu SQL Ćwiczysz Python Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Python Academy?

Nie wymagamy żadnego doświadczenia. Python Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.

Ile czasu zajmuje lekcja „Zapytania parametryzowane”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Python Academy?

Tak. Każda lekcja Python Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Łączenie i tworzenie tabel
  2. Insert, Select, Update, Delete
  3. Zapytania parametryzowane
  4. Transakcje i menedżery kontekstu
← Powrót do Python Academy