python如何防止SQL注入攻击?

python如何防止SQL注入攻击?

在您提供的 ORM 示例中,我们已经有了防止 SQL 注入的基本保障,因为我们使用了参数化查询。但是,为了进一步增强代码的清晰性和安全性,我们可以确保在分页查询和插入等操作中都使用参数化查询,同时加入类型验证以防止意外输入。

以下是修改后的 ORM 代码,加入了更全面的安全措施和分页功能:

import sqlite3
from abc import ABC, abstractmethod


class Database:
    """数据库连接管理类"""
    
    def __init__(self, db_name):
        self.connection = sqlite3.connect(db_name)
        self.cursor = self.connection.cursor()

    def commit(self):
        self.connection.commit()

    def close(self):
        self.connection.close()


class BaseModel(ABC):
    """模型基类"""
    
    @classmethod
    @abstractmethod
    def table_name(cls):
        pass

    @classmethod
    def create_table(cls, db: Database):
        """创建表"""
        raise NotImplementedError("Subclasses must implement this method.")
    
    @classmethod
    def all(cls
防止 SQL 注入攻击的核心方法是**不直接拼接用户输入到 SQL 语句中**,而是使用 **参数化查询(预编译语句)** 或 ORM 框架。SQL 注入通常通过构造恶意的输入来篡改 SQL 查询逻辑,从而执行非授权的操作。 下面以 Python 和 MySQL 为例,展示如何使用参数化查询来防止 SQL 注入。 --- ### ✅ 使用参数化查询(推荐) ```python import mysql.connector # 连接到MySQL数据库 conn = mysql.connector.connect( host="localhost", user="root", password="yourpassword", database="yourdatabase" ) cursor = conn.cursor() # 用户输入(模拟用户输入) name = input("请输入员工姓名:") department = input("请输入部门:") salary = float(input("请输入工资:")) # 插入数据(参数化查询) insert_query = """ INSERT INTO employee (name, department, salary) VALUES (%s, %s, %s) """ cursor.execute(insert_query, (name, department, salary)) conn.commit() print("记录插入成功") # 更新数据(参数化查询) new_salary = 5500.00 update_query = """ UPDATE employee SET salary = %s WHERE name = %s """ cursor.execute(update_query, (new_salary, name)) conn.commit() print("记录更新成功") # 删除数据(参数化查询) delete_query = """ DELETE FROM employee WHERE name = %s """ cursor.execute(delete_query, (name,)) conn.commit() print("记录删除成功") cursor.close() conn.close() ``` **解释:** - `%s` 是占位符,不是字符串格式化操作。 - `cursor.execute()` 的第二个参数是一个元组,数据库驱动会自动对其中的内容进行转义和处理。 - 即使用户输入了类似 `' OR '1'='1` 这样的恶意内容,也不会影响 SQL 的结构。 --- ### ✅ 使用 ORM 框架(如 SQLAlchemy) ORM 框架(例如 SQLAlchemy、Django ORM)内部已经封装了参数化查询机制,可以天然防止 SQL 注入。 示例(使用 SQLAlchemy): ```python from sqlalchemy import create_engine, Column, Integer, String, Numeric from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker Base = declarative_base() class Employee(Base): __tablename__ = 'employee' id = Column(Integer, primary_key=True) name = Column(String(100), nullable=False) department = Column(String(100)) salary = Column(Numeric(10, 2)) engine = create_engine("mysql+mysqlconnector://root:yourpassword@localhost/yourdatabase") Session = sessionmaker(bind=engine) session = Session() # 插入数据 new_employee = Employee(name="John Doe", department="HR", salary=5000.00) session.add(new_employee) session.commit() # 更新数据 employee = session.query(Employee).filter(Employee.name == "John Doe").first() if employee: employee.salary = 5500.00 session.commit() # 删除数据 session.delete(employee) session.commit() ``` **解释:** - 所有数据库操作都通过 ORM 接口完成,不会直接暴露 SQL 语句。 - 极大降低 SQL 注入风险。 --- ### ❌ 不安全的写法(容易被注入) ```python # ⚠️ 不安全的做法 name = input("请输入姓名:") cursor.execute(f"SELECT * FROM employee WHERE name = '{name}'") ``` 如果用户输入: ``` ' OR '1'='1 ``` 最终执行的 SQL 会变成: ```sql SELECT * FROM employee WHERE name = '' OR '1'='1' ``` 这将返回所有记录,造成信息泄露或更严重的后果。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值