PyMySQL防止SQL注入

1、SQL注入簡介python

    SQL注入是比較常見的網絡攻擊方式之一,它不是利用操做系統的BUG來實現攻擊,而是針對程序員編程時的疏忽,經過SQL語句,實現無賬號登陸,甚至篡改數據庫mysql

2、SQL注入攻擊的整體思路程序員

1.尋找到SQL注入的位置sql

2.判斷服務器類型和後臺數據庫類型數據庫

3.針對不通的服務器和數據庫特色進行SQL注入攻擊編程

 

3、SQL注入攻擊實例服務器

 一、字符串拼接查詢,形成注入網絡

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()

其實用戶能夠這樣輸入實現免賬號登陸:ide

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 那麼這個條件必定會成功;而後後面加兩個-,這意味着註釋,它將後面的語句註釋,讓他們不起做用,這樣語句永遠都能正確執行,用戶輕易騙過系統,獲取合法身份。

解決方法:

一、使用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注入漏洞。

二、使用存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
相關文章
相關標籤/搜索