SQL注入是什么?如何用代码防范?

2025-10发布6次浏览

SQL注入是一种常见的网络攻击技术,攻击者通过在输入字段中插入或“注入”恶意SQL代码,来操控数据库服务器执行非预期的操作。这种攻击可以允许攻击者获取、修改或删除数据库中的数据,甚至执行任意命令,从而对系统安全构成严重威胁。

SQL注入的工作原理

SQL注入通常发生在应用程序没有正确验证或过滤用户输入的情况下。当用户输入的数据被直接拼接到SQL查询语句中时,攻击者可以通过输入特殊构造的字符串来改变SQL语句的原意。例如,如果应用程序使用用户输入来构建一个查询,如:

SELECT * FROM users WHERE username = 'admin'

如果用户在输入框中输入 ' OR '1'='1,那么SQL查询可能会变成:

SELECT * FROM users WHERE username = '' OR '1'='1'

由于 '1'='1' 总是为真,这个查询会返回数据库中所有用户的信息,从而绕过了认证。

防范SQL注入的方法

为了防范SQL注入,可以采取以下几种措施:

  1. 使用参数化查询:参数化查询是防范SQL注入最有效的方法之一。通过使用参数而不是将用户输入直接拼接到SQL语句中,可以确保用户输入被当作数据处理,而不是SQL代码的一部分。在Python中,可以使用sqlite3模块的参数化查询:

    import sqlite3
    
    conn = sqlite3.connect('example.db')
    cursor = conn.cursor()
    
    username = input("Enter username: ")
    cursor.execute("SELECT * FROM users WHERE username = ?", (username,))
    results = cursor.fetchall()
    for row in results:
        print(row)
    
  2. 使用预编译语句:预编译语句(Prepared Statements)可以确保SQL语句的结构在执行前就已经确定,用户输入被当作参数传递,从而避免了SQL代码的注入。

  3. 输入验证和过滤:对用户输入进行严格的验证和过滤,确保输入符合预期的格式。例如,可以使用正则表达式来验证输入是否只包含合法字符。

  4. 最小权限原则:数据库用户应该只有执行必要操作的权限,避免使用具有过高权限的账户进行日常操作。

  5. 错误处理:合理配置数据库错误处理,避免将敏感信息(如数据库结构)泄露给用户。

示例代码

下面是一个使用参数化查询的示例,展示了如何在Python中防范SQL注入:

import sqlite3

def fetch_user(username):
    conn = sqlite3.connect('example.db')
    cursor = conn.cursor()
    try:
        cursor.execute("SELECT * FROM users WHERE username = ?", (username,))
        results = cursor.fetchall()
        for row in results:
            print(row)
    except sqlite3.DatabaseError as e:
        print(f"Database error: {e}")
    finally:
        conn.close()

# 正常用户输入
fetch_user("admin")

# 恶意用户输入
fetch_user("admin' OR '1'='1")

在这个示例中,即使用户输入了恶意的SQL代码,也不会影响查询的正常执行,因为用户输入被当作参数处理,而不是SQL代码的一部分。