• 第二百八十一节,MySQL数据库-SQL注入和pymysql模块防止SQL注入


    MySQL数据库-SQL注入和pymysql模块防止SQL注入

    SQL注入就是通过SQL语句绕开程序判断,获取到数据库的内容

    下面以一个简单的程序登录SQL注入举例:

    正常登录

    1、数据库有一张会员表

    2、用户输入账号和密码,到数据库查找此用户是否存在,存在登录成功,不存在登录失败

    #!/usr/bin/env python
    #coding:utf-8
    
    import tornado.ioloop
    import tornado.web                                              #导入tornado模块下的web文件
    import pymysql                                                  #导入数据库模块
    
    class khdHandler(tornado.web.RequestHandler):
        def get(self):
            self.render("khd.html")
        def post(self):
            yhm = self.get_argument('yhm')  #接收用户名
            mim = self.get_argument('mim')  #接收密码
    
            #连接数据库
            conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='279819', db='cshi',charset='utf8')
            # 创建游标
            cursor = conn.cursor()
    
            temp = "select yhm from yhxx where yhm='%s' and mim='%s'"%(yhm,mim) #字符串拼接SQL查询语句
            print(temp)
    
            # 执行SQL,并返回收影响行数
            effect_row = cursor.execute(temp)
    
            shuju = cursor.fetchall()  # 获取游标里的数据
            print(shuju)
            # 提交,不然无法保存新建或者修改的数据
            # conn.commit()
    
            # 关闭游标
            cursor.close()
            # 关闭连接
            conn.close()
            
            
            if shuju:                       #判断数据库存在用户
                self.write('登录成功')       #登录成功
            else:                           #数据库不存在用户
                self.write('登录失败')       #登录失败
    
    
    settings = {                                            #html文件归类配置,设置一个字典
        "template_path":"views",                            #键为template_path固定的,值为要存放HTML的文件夹名称
        "static_path":"statics",                            #键为static_path固定的,值为要存放js和css的文件夹名称
    }
    
    #路由映射
    application = tornado.web.Application([                 #创建一个变量等于tornado.web下的Application方法
        (r"/khd", khdHandler),
    ],**settings)                                           #将html文件归类配置字典,写在路由映射的第二个参数里
    
    if __name__ == "__main__":
        #内部socket运行起来
        application.listen(8002)                            #设置端口
        tornado.ioloop.IOLoop.instance().start()

    3、正常登录

    #!/usr/bin/env python
    #coding:utf-8
    
    import tornado.ioloop
    import tornado.web                                              #导入tornado模块下的web文件
    import pymysql                                                  #导入数据库模块
    
    class khdHandler(tornado.web.RequestHandler):
        def get(self):
            self.render("khd.html")
        def post(self):
            yhm = self.get_argument('yhm')  #接收用户名
            mim = self.get_argument('mim')  #接收密码
    
            #连接数据库
            conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='279819', db='cshi',charset='utf8')
            # 创建游标
            cursor = conn.cursor()
    
            temp = "select yhm from yhxx where yhm='%s' and mim='%s'"%(yhm,mim) #字符串拼接SQL查询语句
            print(temp)
    
            # 执行SQL,并返回收影响行数
            effect_row = cursor.execute(temp)
    
            shuju = cursor.fetchall()  # 获取游标里的数据
            print(shuju)
            # 提交,不然无法保存新建或者修改的数据
            # conn.commit()
    
            # 关闭游标
            cursor.close()
            # 关闭连接
            conn.close()
    
    
            if shuju:                       #判断数据库存在用户
                self.write('登录成功')       #登录成功
            else:                           #数据库不存在用户
                self.write('登录失败')       #登录失败
    
    
    settings = {                                            #html文件归类配置,设置一个字典
        "template_path":"views",                            #键为template_path固定的,值为要存放HTML的文件夹名称
        "static_path":"statics",                            #键为static_path固定的,值为要存放js和css的文件夹名称
    }
    
    #路由映射
    application = tornado.web.Application([                 #创建一个变量等于tornado.web下的Application方法
        (r"/khd", khdHandler),
    ],**settings)                                           #将html文件归类配置字典,写在路由映射的第二个参数里
    
    if __name__ == "__main__":
        #内部socket运行起来
        application.listen(8002)                            #设置端口
        tornado.ioloop.IOLoop.instance().start()

    实际SQL查询语句

    select yhm from yhxx where yhm='张三' and mim='123456'

    数据库返回

    (('张三',),)    返回了元祖类型的数据库查到的数据

    SQL注入绕开密码

    实际SQL查询语句

    select yhm from yhxx where yhm='张三' -- j' and mim='789'

    可以看到实际用户密码已经被注释了,也就不起作用了,只要用户名存在就可以登录,对于密码已经失效

    SQL注入绕开用户名和密码

    实际SQL查询语句

    -- 查询yhxx表的yhm字典等于张飞,或者 1 = 1,即使yhm字段没有张飞,也能查询到所有数据
    select yhm from yhxx where yhm='张飞' or 1 = 1 -- d' and mim='789'

    可以看到实际SQL查询语句,已经绕开了用户名和密码,直接获取了全部数据

    pymysql模块防止SQL注入

    pymysql模块的execute()方法,的参数2 字符串占位符变量,在参数2格式化SQL语句字符串,会自动调用pymysql模块里的mogrify()方法,将第二个参数的字符串里含有'号转化成号,这样就防止了SQL注入

    #!/usr/bin/env python
    #coding:utf-8
    
    import tornado.ioloop
    import tornado.web                                              #导入tornado模块下的web文件
    import pymysql                                                  #导入数据库模块
    
    class khdHandler(tornado.web.RequestHandler):
        def get(self):
            self.render("khd.html")
        def post(self):
            yhm = self.get_argument('yhm')  #接收用户名
            mim = self.get_argument('mim')  #接收密码
    
            #连接数据库
            conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='279819', db='cshi',charset='utf8')
            # 创建游标
            cursor = conn.cursor()
    
            #查看execute()方法调用的mogrify()方法,将接收到的数据,会把有'转换成
            quer = cursor.mogrify("select yhm from yhxx where yhm=%s and mim=%s",(yhm,mim))
            print(quer)
    
    
            # 执行SQL,并返回收影响行数
            effect_row = cursor.execute("select yhm from yhxx where yhm=%s and mim=%s",(yhm,mim))
    
            shuju = cursor.fetchall()  # 获取游标里的数据
            print(shuju)
            # 提交,不然无法保存新建或者修改的数据
            # conn.commit()
    
            # 关闭游标
            cursor.close()
            # 关闭连接
            conn.close()
    
    
            if shuju:                       #判断数据库存在用户
                self.write('登录成功')       #登录成功
            else:                           #数据库不存在用户
                self.write('登录失败')       #登录失败
    
    
    settings = {                                            #html文件归类配置,设置一个字典
        "template_path":"views",                            #键为template_path固定的,值为要存放HTML的文件夹名称
        "static_path":"statics",                            #键为static_path固定的,值为要存放js和css的文件夹名称
    }
    
    #路由映射
    application = tornado.web.Application([                 #创建一个变量等于tornado.web下的Application方法
        (r"/khd", khdHandler),
    ],**settings)                                           #将html文件归类配置字典,写在路由映射的第二个参数里
    
    if __name__ == "__main__":
        #内部socket运行起来
        application.listen(8002)                            #设置端口
        tornado.ioloop.IOLoop.instance().start()

    被mogrify()方法,转换后的实际SQL语句

    select yhm from yhxx where yhm='张飞' or 1 = 1 -- d' and mim='123456'

    可以看到用户输入的'已经被转换成了了,这样就防止了SQL注入

  • 相关阅读:
    MySQL——事务,索引
    Python——多线程
    Python输入输出
    MySQL与Python的交互——增删改
    MySQL与Python的交互————查询
    Python的学习路
    MySQL数据库
    MySQL条件查询
    设计模式笔记 抽象工厂模式
    设计模式笔记 建造者模式
  • 原文地址:https://www.cnblogs.com/adc8868/p/6984841.html
Copyright © 2020-2023  润新知