Python中常见的SQL注入攻击模式

2023-04-17 00:00:00 注入 攻击 常见
  1. 直接拼接SQL语句会导致SQL注入攻击。
    示例代码:
import MySQLdb
def login(username, password):
    db = MySQLdb.connect("localhost", "root", "123456", "test", charset='utf8')
    cursor = db.cursor()
    sql = "SELECT * FROM user WHERE username = '" + username + "' AND password = '" + password + "'"
    cursor.execute(sql)
    data = cursor.fetchone()
    db.close()
    return data

攻击方式:
假设我们使用的用户名为:pidancode.com,密码为:password' OR '1'='1
则构造的SQL语句为:

SELECT * FROM user WHERE username = 'pidancode.com' AND password = 'password' OR '1'='1'

这样就可以通过任意输入密码绕过登录验证。
解决方案:
使用参数化查询,将参数传入SQL语句中。
示例代码:

import MySQLdb
def login(username, password):
    db = MySQLdb.connect("localhost", "root", "123456", "test", charset='utf8')
    cursor = db.cursor()
    sql = "SELECT * FROM user WHERE username = %s AND password = %s"
    params = (username, password)
    cursor.execute(sql, params)
    data = cursor.fetchone()
    db.close()
    return data
  1. 在SQL语句中使用常量,容易导致SQL注入攻击。
    示例代码:
import MySQLdb
def search(name):
    db = MySQLdb.connect("localhost", "root", "123456", "test", charset='utf8')
    cursor = db.cursor()
    sql = "SELECT * FROM products WHERE name = '" + name + "'"
    cursor.execute(sql)
    data = cursor.fetchall()
    db.close()
    return data

攻击方式:
假设我们要查询的商品名称为:皮蛋编程' OR '1'='1
则构造的SQL语句为:

SELECT * FROM products WHERE name = '皮蛋编程' OR '1'='1'

这样就可以查找到所有商品了。
解决方案:
使用参数化查询,将参数传入SQL语句中。
示例代码:

import MySQLdb
def search(name):
    db = MySQLdb.connect("localhost", "root", "123456", "test", charset='utf8')
    cursor = db.cursor()
    sql = "SELECT * FROM products WHERE name = %s"
    params = (name,)
    cursor.execute(sql, params)
    data = cursor.fetchall()
    db.close()
    return data
  1. 在SQL语句中使用LIKE模糊匹配,容易导致SQL注入攻击。
    示例代码:
import MySQLdb
def search(keyword):
    db = MySQLdb.connect("localhost", "root", "123456", "test", charset='utf8')
    cursor = db.cursor()
    sql = "SELECT * FROM products WHERE name LIKE '%" + keyword + "%'"
    cursor.execute(sql)
    data = cursor.fetchall()
    db.close()
    return data

攻击方式:
假设我们要查询的关键词为:' OR '1'='1
则构造的SQL语句为:

SELECT * FROM products WHERE name LIKE '%'' OR '1'='1%'

这样就可以查找到所有商品了。
解决方案:
使用参数化查询,将参数传入SQL语句中。
示例代码:

import MySQLdb
def search(keyword):
    db = MySQLdb.connect("localhost", "root", "123456", "test", charset='utf8')
    cursor = db.cursor()
    sql = "SELECT * FROM products WHERE name LIKE %s"
    params = ('%' + keyword + '%',)
    cursor.execute(sql, params)
    data = cursor.fetchall()
    db.close()
    return data
  1. 在SQL语句中使用子查询,容易导致SQL注入攻击。
    示例代码:
import MySQLdb
def login(username, password):
    db = MySQLdb.connect("localhost", "root", "123456", "test", charset='utf8')
    cursor = db.cursor()
    sql = "SELECT * FROM user WHERE username = '" + username + "' AND password = (SELECT password FROM user WHERE username = '" + username + "')"
    cursor.execute(sql)
    data = cursor.fetchone()
    db.close()
    return data

攻击方式:
与拼接SQL语句类似,将注入代码作为子查询的结果返回。
假设我们使用的用户名为:pidancode.com' OR password IN (SELECT password FROM user WHERE username='pidancode.com')
则构造的SQL语句为:

SELECT * FROM user WHERE username = 'pidancode.com' AND password = (SELECT password FROM user WHERE username = 'pidancode.com' OR password IN (SELECT password FROM user WHERE username='pidancode.com'))

这样就可以绕过登录验证。
解决方案:
禁止使用子查询,或对子查询的结果进行校验。

相关文章