首页 > 数据库 >Django项目利用安全库规避SQL注入

Django项目利用安全库规避SQL注入

来源:互联网 2026-07-08 08:31:01

DjangoORM仅对值参数化,字段名等结构参数需白名单校验。filter()动态字段名、raw()和extra()参数化、RawSQL中LIKE手动转义及ORDERBY等结构字段均为注入风险点,需严格规避用户直接控制。

Django ORM防SQL注入,你需要打破的三个误解

许多开发者容易忽略一个核心判断:Django ORM在防止SQL注入方面,只保护了“值”这一层。字段名、表名等结构参数,它根本不管。市面上流行的“引入安全库”建议,反而可能让人忽视真正的关键控制点。

与其依赖第三方库,不如先把Django ORM自带的防御机制吃透——参数化查询是默认武器,配合白名单校验,覆盖绝大多数场景完全够用。

长期稳定更新的攒劲资源: >>>点此立即查看<<<

Django项目利用安全库规避SQL注入

filter()里动态字段名:一个容易被忽略的“后门”

很多人的代码写成filter(**{request.GET.get('field'): value}),然后想当然认为ORM会把整个表达式过滤一遍。可惜不会。Django的绑定机制只对值生效,对键名完全不做校验。

试想一下,攻击者传入is_staff__gt_meta.model_namepassword__contains,结果会怎样?轻则泄露敏感字段,重则直接触发越权查询。这并非危言耸听。

正确做法其实很基础:先做白名单检查。比如if field_name not in ['title', 'author__name', 'status'],再用getattr(MyModel, field_name, None)确认字段真实存在且不是property。更关键的是,千万别用Q("username = '{}'".format(u))拼字符串——应改用Q(**{field_name + '__icontains': u}),后者才是ORM安全边界内的写法。

raw()和extra():原生SQL入口,注入高发区

这两个方法是ORM里唯二允许写原生SQL的地方,也是最容易出问题的区域。它们不继承filter()的安全逻辑,在其内部拼字符串就是在自找麻烦。

先说raw():安全写法必须是User.objects.raw("SELECT * FROM auth_user WHERE username = %s", params=[username])。这里有两个细节必须注意:params必须是列表或元组;占位符只能用%s,不能用{}%(name)s——SQLite不支持命名参数。

再说extra():很多人以为extra(where=["status = %s"], params=[u])是安全的,但事实是extra()params参数在Django内部会被忽略。所以where字符串里绝对不能出现用户输入。如果真要实现动态条件,最稳妥的办法是提前用Q组合 + filter()替代,而不是把逻辑硬塞进extra()

RawSQL和annotate()中的LIKE:手动转义不能省

RawSQL的机制有点特殊:它只对params对应的占位符做参数化,整个表达式本身并不会自动转义。这意味着,一旦漏掉%_的转义,它们就会变成SQL通配符,轻则造成逻辑漏洞,重则拖垮数据库。

错误示范:annotate(score=RawSQL(f"CASE WHEN title LIKE '%{search}%' THEN 1 ELSE 0 END"))。这种写法等于直接把用户输入扔进了SQL模板。

正确写法应该是:RawSQL("CASE WHEN title LIKE %s THEN 1 ELSE 0 END", params=[f"%{search}%"])。但这还不够稳妥——更推荐的做法是用ORM原生表达式:Case(When(title__icontains=search, then=1), output_field=IntegerField())。原生表达式会自动处理转义,还能利用数据库索引,一举两得。

如果确实必须用原生LIKE,那就调用connection.ops.prep_for_like_query(search)手动转义。

最容易被忽视的那个坑:结构参数

最后说一个最容易被忽略的“隐蔽角落”:字段名、表名、ORDER BYGROUP BY、函数名。这些结构参数,参数绑定机制根本管不到——params=对它们来说形同虚设。

哪怕是代码里100%没拼过任何SQL字符串,只要写了order_by(request.GET.get('o'))而没有做白名单校验,攻击者就能通过这个入口触发全表扫描,或者暴露索引信息。这才是Django防SQL注入这场战役中,真正需要警惕的“主力对手”。

侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述

热游推荐

更多
湘ICP备14008430号-1 湘公网安备 43070302000280号
All Rights Reserved
本站为非盈利网站,不接受任何广告。本站所有软件,都由网友
上传,如有侵犯你的版权,请发邮件给xiayx666@163.com
抵制不良色情、反动、暴力游戏。注意自我保护,谨防受骗上当。
适度游戏益脑,沉迷游戏伤身。合理安排时间,享受健康生活。