一:场景、演示
场景:查询等拼接SQL和参数的问题,博主为了演示,这里写一个有注入风险的接口,请勿模仿
class PostMan(View):
def get(self, request):
aa = request.GET.get('aa')
with connections['default'].cursor() as cursor:
sql = 'select * from sys_dict where pid = %s'%(aa)
cursor.execute(sql)
result = cursor.fetchall()
print(result)
return api_response(code=200,msg='aaa',data=result)
二:注入测试,这里采用sqlmap检测(通过postman等传入" or 1=1 or " 也能看到效果)。
- sqlmap安装及测试:github 下载安装包,解压,进入sqlmap.py同级目录,输入以下命令测试
python sqlmap.py -hh
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2csAjVtJ2a5IjW1I0MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL3ITNwADO1gDM3ATMwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
2. 注入检测,-u 后跟的是视图对应的接口地址
- 注入结果查看,终端查看输出信息或根据日志中的output位置 查看相应日志,如图
危害极大,还可以查询所有表,库,dump数据等,不再赘述,命令可以参考这篇博客sqlmap常见命令
二:Django中sql注入解决方案,主要以下四种:
- 参数化查询,语法如下
sql = '''select * from shixiang_table where id= "%s" limit 10'''
cursor.execute(sql, [pk])
print(data_count)
-
使用ORM组件,flask的sqlalchemy,django的orm
使用orm filter等进行查询操作
- 数据库最小权限原则,满足业务需求的最小权限,如只读账号等
-
危险字符过滤
主要过滤两类字符:(1)一些SQL中的标点符号,如@,*以及单引号等等;(2)过滤数据库关键字insert、delete from、drop table、truncate、mid、delete、update、truncate、declare、master、script、exec、net user、drop等关键字或者关键词。