Python Coding Academy
🐍 آموزش جامع Python — پست ۲۳۰
جلوگیری از SQL Injection در SQLite
وقتی برنامه اطلاعات را از کاربر دریافت میکند، باید هنگام اجرای Queryها مراقب باشیم.
یکی از آسیبپذیریهای مهم در کار با دیتابیس، SQL Injection است؛ زمانی که ورودی کنترلنشده کاربر باعث تغییر ساختار دستور SQL شود.
🔹 روش ناامن
فرض کنیم میخواهیم کاربری را بر اساس نام پیدا کنیم:
username = input("Username: ")
query = f"""
SELECT * FROM users
WHERE username = '{username}'
"""
cursor.execute(query)
در این روش، ورودی کاربر مستقیماً وارد دستور SQL میشود و ممکن است ساختار Query را تغییر دهد.
برای ساخت Query از f-string یا اتصال رشتهها با ورودی کاربر استفاده نکن.
🔹 روش امن با پارامترها
در sqlite3 از Placeholder استفاده میکنیم:
import sqlite3
connection = sqlite3.connect("users.db")
username = input("Username: ")
cursor = connection.execute(
"SELECT id, username FROM users WHERE username = ?",
(username,)
)
print(cursor.fetchall())
connection.close()
علامت ? محل مقدار ورودی را مشخص میکند.
این بخش:
(username,)
یک Tuple تکعضوی است؛ به همین دلیل بعد از username کاما قرار دارد.
SQLite مقدار ورودی را بهعنوان داده پردازش میکند، نه بخشی از ساختار SQL.
🔹 پارامترگذاری در INSERT
همین روش برای ثبت اطلاعات نیز کاربرد دارد:
connection.execute(
"INSERT INTO users (username, age) VALUES (?, ?)",
("Ali", 25)
)
connection.commit()
هر مقدار در Placeholder مربوط به خودش قرار میگیرد.
🔹 پارامترگذاری در UPDATE
connection.execute(
"UPDATE users SET age = ? WHERE username = ?",
(26, "Ali")
)
connection.commit()
ترتیب مقادیر باید با ترتیب Placeholderها مطابقت داشته باشد.
⚠️ نکته مهم
پارامترها برای مقدارها هستند، نه نام جدول یا ستون.
مثلاً نمیتوانیم نام ستون را با ? جایگزین کنیم:
cursor.execute(
"SELECT ? FROM users",
("username",)
)
این دستور ستون username را انتخاب نمیکند؛ بلکه مقدار ثابت "username" را برای هر ردیف برمیگرداند.
اگر نام ستون باید پویا باشد، آن را از یک فهرست مجاز و از پیش تعریفشده انتخاب کن؛ نه مستقیماً از ورودی کاربر.
🧠 خلاصه
ناامن:
f"SELECT ... WHERE name = '{name}'"
امن:
"SELECT ... WHERE name = ?", (name,)
قانون اصلی: برای انتقال داده به Queryهای SQL از Parameterized Query استفاده کن.
🎯 تمرین
جدول products شامل ستونهای id، name و price است.
کدی بنویس که نام محصول را از کاربر بگیرد و محصول را با استفاده از ? جستوجو کند.
شرط مهم: ورودی کاربر نباید با f-string وارد دستور SQL شود.
پست ۲۳۰ از دوره جامع Python 🐍
3 ·