SQL注入实例:避免后端SQL语句拼接操作

1 实例-后端逻辑

以下是基于pymysql的一个例子:

import pymysql
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='mysql', db='user_table', charset='utf-8')
cursor = conn.cursor()

def query_key(key):
    sql = "SELECT name FROM user_info where key_id='{}'".format(key)
    cursor.execute(sql)
    fet = cursor.fetchone()

    if not fet:
        result = "Not Found"
    else:
        result = fet[0]

    print(result)

上面的程序会在用户输入key的时候,将key拼接到SQL语句进行查询。

2 测试漏洞

2.1 测试正常用户行为

key = 10
query_key(key)
# SELECT name FROM user_info where key_id='10'

> Alan

正常查询会正常返回相应id的姓名

2.2 测试注入攻击者行为

key = "' or '1'='1"
query_key(key)
# sql = SELECT name FROM user_info where key_id='' or '1'='1'

> Lee

此时由于注入漏洞sql会查到所有数据,result则会显示第一条数据

2.3 测试注入攻击者行为-提取所有数据

key = "' or '1'='1 limit 1,1"
query_key(key)
# sql = SELECT name FROM user_info where key_id='' or '1'='1' limit 1,1
> Lee

key = "' or '1'='1 limit 2,2"
query_key(key)
# sql = SELECT name FROM user_info where key_id='' or '1'='1' limit 2,1
> Hank

此时攻击者如果对注入语句稍作修改,写脚本遍历数据库,会有数据全部泄露的风险。

3. 修复注入漏洞

使用pymysql参数化查询而非SQL拼接的方式,可以避免注入漏洞,转义非法字符

def query_key(key):
    sql = "SELECT name FROM user_info where key_id=%s"
    cursor.execute(sql, [key])
    fet = cursor.fetchone()

    if not fet:
        result = "Not Found"
    else:
        result = fet[0]

    print(result)

下面总结一下python web日常开发中防止注入漏洞的方法:

使用参数化查询执行原生语句;
使用带有ORM的web框架,比如django;
使用ORM组件sqlalchemy,peewee;
使用正则和字符串方法检测注入风险,比如单引号和注释符号等(不推荐)。

参考链接:

https://blog.dfen.xyz/2018/04/sql-injection.html?m=1

更多文章可以访问我的个人博客:码练

你可能感兴趣的:(数据库,web开发)