当前位置:首页>python>Python SQL注入系列之---WHERE IN 子句漏洞

Python SQL注入系列之---WHERE IN 子句漏洞

  • 2026-09-02 20:29:52
Python SQL注入系列之---WHERE IN 子句漏洞
大家好,今天我们继续来看SQL注入防护系列,WHERE IN 子句因为常用来处理逗号分隔的参数列表,也就成了攻击者的高频目标,今天我们将分析一下这类漏洞的成因、供给手法,和常见的解决方案。
很多开发者觉得只要参数是数字,例如1,2,3就不会有问题,但是攻击者可以通过构造特殊的payload来突破限制,利用 ) 闭合 IN 子句的括号,再注入UNION查询语句,最后用--注释掉后续的无效代码。让我们看个例子:
category_ids = "1) UNION SELECT id, username, password_hash FROM admin_users--"
注入后执行的SQL语句变成
SELECT id, name, price FROM products WHERE category_id IN (1) UNION SELECT id, username, password_hash FROM admin_users--                                                              ↑        ↑                                      ↑↑                                                      闭合IN子句   注入UNION查询               注释掉原语句剩余的)
执行结果就是,可以直接读取管理员表admin_users的账号、密码哈希等敏感数据。那么要如何来解决呢?针对动态IN子句,核心是参数化查询,让我们以Python Flask + pyMysql的示例来看看是如何修复的:
import pymysqlfrom flask import Flask, request, jsonifyapp = Flask(__name__)@app.route('/products/filter', methods=['GET'])def filter_products():    # 1. 获取前端传入的分类ID参数,默认值为1    category_ids = request.args.get('categories', '1')    # 2. 拆分参数并严格验证类型(仅允许整数)    id_list = category_ids.split(',')    try:        # 去除空格并强制转换为整数,非数字直接抛出异常        id_list = [int(x.strip()) for x in id_list]    except ValueError:        # 验证失败返回400错误,阻断恶意输入        return jsonify({"error": "Invalid category IDs"}), 400    # 3. 动态生成与参数数量匹配的占位符(避免拼接SQL)    placeholders = ','.join(['%s'] * len(id_list))    # 4. 建立数据库连接并执行参数化查询    conn = pymysql.connect(        host='localhost',         user='app',         password='pass',         database='shop'    )    cursor = conn.cursor()    # 关键:SQL语句使用占位符,参数通过execute第二个参数传入    query = f"SELECT id, name, price FROM products WHERE category_id IN ({placeholders})"    cursor.execute(query, tuple(id_list))  # 自动转义参数,杜绝注入    # 5. 获取结果并关闭连接    results = cursor.fetchall()    conn.close()    return jsonify({"products": results})if __name__ == '__main__':    app.run(debug=False)  # 生产环境务必关闭debug模式
它的核心思路就是,强制将category_ids转换为整数,只要不是数字直接拒绝;根据参数数量动态生成%s占位符,避免直接拼接SQL语句;最后通过cursor.execute(query,参数元组)方式传递参数,数据库驱动会自动转义特殊字符,彻底阻断注入。
虽然,我们使用的是Python示例,但是核心逻辑在其它的语言应用中国同样适用,以后再有类似的情况,可以尝试着试试。

最新文章

随机文章