zoukankan      html  css  js  c++  java
  • PyMySQL防止SQL注入

    一、SQL注入简介

        SQL注入是比较常见的网络攻击方式之一,它不是利用操作系统的BUG来实现攻击,而是针对程序员编程时的疏忽,通过SQL语句,实现无帐号登录,甚至篡改数据库

    二、SQL注入攻击的总体思路

    1.寻找到SQL注入的位置

    2.判断服务器类型和后台数据库类型

    3.针对不通的服务器和数据库特点进行SQL注入攻击

    三、SQL注入攻击实例

     1、字符串拼接查询,造成注入

    import pymysql
    
    conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='User')
    cursor = conn.cursor()
    username=input()
    password =input()
    # 正常构造语句的情况
    sql = "select user,pwd from User where user='%s' and pwd='%s'" % (username,password)
    
    row_count = cursor.execute(sql)
    row_1 = cursor.fetchone()
    print(row_count, row_1)
    conn.commit()
    cursor.close()
    conn.close()

    其实用户可以这样输入实现免帐号登录:

    username: ‘or 1 = 1 –-

    password:

    如若没有做特殊处理,那么这个非法用户直接登陆进去了.

    当输入了上面的用户名和密码,服务端的sql就变成:

    sql = "select user,pwd from User where user=‘'or 1 = 1 –-' and pwd='%s'"

    因为条件后面username=”or 1=1 用户名等于 ” 或1=1 那么这个条件一定会成功;然后后面加两个-,这意味着注释,它将后面的语句注释,让他们不起作用,这样语句永远都能正确执行,用户轻易骗过系统,获取合法身份。

    解决方法:

    1、使用pymysql提供的参数化语句防止注入

    #! /usr/bin/env python
    # -*- coding:utf-8 -*-
    import pymysql
     
    conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='User')
    cursor = conn.cursor()
    username= input()
    password =input()
    
    #执行参数化查询
    row_count=cursor.execute("select user,pwd from User where user='%s' and pwd='%s'" ,(username,password))
    #execute()函数本身就有接受SQL语句变量的参数位,只要正确的使用(直白一点就是:使用”逗号”,而不是”百分号”)就可以对传入的值进行correctly转义,从而避免SQL注入的发生。
    
    
    #内部执行参数化生成的SQL语句,对特殊字符进行了加转义,避免注入语句生成。
    # sql=cursor.mogrify("select user,pwd from User where user='%s' and pwd='%s'" ,(username,password))
    # print (sql)
     
    row_1 = cursor.fetchone()
    print(row_count,row_1)
     
    conn.commit()
    cursor.close()
    conn.close()
    View Code

    注意:excute执行SQL语句的时候,必须使用参数化的方式,否则必然产生SQL注入漏洞。

    2、使用存mysql储过程动态执行SQL防注入

      使用MYSQL存储过程自动提供防注入,动态传入SQL到存储过程执行语句。

    delimiter \
    DROP PROCEDURE IF EXISTS proc_sql \
    CREATE PROCEDURE proc_sql (
      in nid1 INT,
      in nid2 INT,
      in callsql VARCHAR(255)
      )
    BEGIN
      set @nid1 = nid1;
      set @nid2 = nid2;
      set @callsql = callsql;
        PREPARE myprod FROM @callsql;
    --   PREPARE prod FROM 'select * from tb2 where nid>? and nid<?';  传入的值为字符串,?为占位符
    --   用@p1,和@p2填充占位符
        EXECUTE myprod USING @nid1,@nid2;
      DEALLOCATE prepare myprod;
     
    END\
    delimiter ;
    View Code
    set @nid1=12;
    set @nid2=15;
    set @callsql = 'select * from User where nid>? and nid<?';
    CALL proc_sql(@nid1,@nid2,@callsql)

    pymsql中调用

    #! /usr/bin/env python
    # -*- coding:utf-8 -*-
    import pymysql
     
    conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='User')
    cursor = conn.cursor()
    mysql="select * from User where nid>? and nid<?"
    cursor.callproc('proc_sql', args=(11, 15, mysql))
     
    rows = cursor.fetchall()
    print (rows #((12, 'u1', 'u1pass', 11111), (13, 'u2', 'u2pass', 22222), (14, 'u3', 'u3pass', 11113)))
    conn.commit()
    cursor.close()
    conn.close()
    View Code
  • 相关阅读:
    Java学习10.22(Javaweb对输入信息进行验证——常用的方法)
    mysql with python
    Linux
    Python 基础的一些习题
    Python 推导式、迭代器、生成器、模块和包
    Python 文件操作、异常
    Python 部分内置函数、作用域、闭包、递归
    Python 基础函数、解包
    Python 条件与循环
    Python 集合、字典、运算符
  • 原文地址:https://www.cnblogs.com/freely/p/6798717.html
Copyright © 2011-2022 走看看