python Web安全之防止SQL注入

2021-09-06 20:20:53 字數 4060 閱讀 9058

伴隨著web2.0、社交網路、微博等一系列新型網際網路產品的興起,基於web環境的網際網路應用越來越廣泛,web攻擊的手段也越來越多樣,web安全史上的乙個重要里程碑是大約2023年發現的sql注入攻擊,之後的xss,csrf等攻擊手段愈發強大,web攻擊的思路也從服務端轉向了客戶端,轉向了瀏覽器和使用者。

在安全領域,一般用帽子的顏色來比喻黑客的善與惡,白帽子是指那些工作在反黑客領域的技術專家,這個群體是」善」的的象徵;而黑帽子則是指那些利用黑客技術造成破壞甚至謀取私利造成犯罪的群體,他們是」惡」的代表。

「白帽子」和」黑帽子」是兩個完全對立的群體。對於黑帽子而言,他們只要找到系統的乙個切入點就可以達到入侵破壞的目的,而白帽子必須將自己系統所有可能被突破的地方都設防,以保證系統的安全執行。

這看起來好像是不公平的,但是安全世界裡的規則就是這樣,可能我們的**1000處都布防的很好,考慮的很周到,但是只要有乙個地方疏忽了,攻擊者就會利用這個點進行突破,讓我們另外的1000處努力白費。

一般說來,在web安全領域,常見的攻擊方式大概有以下幾種:

1、sql注入攻擊

2、跨站指令碼攻擊 - xss

3、跨站偽造請求攻擊 - csrf

4、檔案上傳漏洞攻擊

5、分布式拒絕服務攻擊 - ddos

from pymysql import *

def main():

find_name = input("請輸入物品名稱:")

# 建立connection連線

conn = connect(host='localhost',port=3306,user='root',password='mysql',database='jing_dong',charset='utf8')

# 獲得cursor物件

cs1 = conn.cursor()

# # 非安全的方式

# # 輸入 " or 1=1 or " (雙引號也要輸入)

# sql = 'select * from goods where name="%s"' % find_name

# print("""sql===>%s<====""" % sql)

# # 執行select語句,並返回受影響的行數:查詢所有資料

# count = cs1.execute(sql)

# 安全的方式

# 構造引數列表

params = [find_name]

# 執行select語句,並返回受影響的行數:查詢所有資料

count = cs1.execute('select * from goods where name=%s', params)

# 注意:

# 如果要是有多個引數,需要進行引數化

# 那麼params = [數值1, 數值2....],此時sql語句中有多個%s即可

# 列印受影響的行數

print(count)

# 獲取查詢的結果

# result = cs1.fetchone()

result = cs1.fetchall()

# 列印查詢的結果

print(result)

# 關閉cursor物件

cs1.close()

# 關閉connection物件

conn.close()

if __name__ == '__main__':

main()

這種用法就是常見的拼接字串導致sql注入漏洞的產生。看到這個突然想到上個禮拜drupal水滴的那個漏洞,其並不是預編譯語句被繞過了。而是在構造帶入的預編譯語句的時候拼接了使用者輸入字串,還未帶入查詢的預編譯語句已經被注入了,之後帶入正確的引數,最後被注入了

正確用法:

execute() 函式本身有接受sql語句引數位的,可以通過python自身的函式處理sql注入問題。

使用如此引數帶入方式,python會自動過濾params中的特殊字元,制止sql注入的產生。

execute()函式本身就有接受sql語句變數的引數位,只要正確的使用(直白一點就是:使用」逗號」,而不是」百分號」)就可以對傳入的值進行correctly轉義,從而避免sql注入的發生。

如果目標web**開啟了錯誤顯示,攻擊者就可以通過反覆調整傳送的引數、檢視頁面列印的錯誤資訊,推測出web**使用的資料庫和開發語言等重要資訊。

除非運維人員疏忽,否則大部分的web運營**應該都關閉了錯誤提示資訊,此時攻擊者一般會採用盲注的技巧來進行反覆的嘗試判斷。 仍然以上面的資料表user為例,我們之前的檢視會員詳情頁面的url位址為userinfo.php?username=plhwin,此時黑客分別訪問userinfo.php?username=plhwin' and 1=1-- hackuserinfo.php?username=plhwin' and 1=2-- hack,如果前者訪問能返回正常的資訊而後者不能,就基本可以判斷此**存在sql注入漏洞,因為後者的1=2這個表示式永遠不成立,所以即使username傳入了正確的引數也無法通過,由此可以推斷這個頁面存在sql注入漏洞,並且可以通過username引數進行注入。

對於伺服器配置層面的防範,應該保證生產環境的webserver是關閉錯誤資訊的,比如php在生產環境的配置檔案php.ini中的display_errors應該設定為off,這樣就關閉了錯誤提示,下面我們更多的從編碼的角度來看看如何防範sql注入。

上面用兩個例項分析了sql注入攻擊的技巧,可以看到,但凡有sql注入漏洞的程式,都是因為程式要接受來自客戶端使用者輸入的變數或url傳遞的引數,並且這個變數或引數是組成sql語句的一部分,對於使用者輸入的內容或傳遞的引數,我們應該要時刻保持警惕,這是安全領域裡的「外部資料不可信任」的原則,縱觀web安全領域的各種攻擊方式,大多數都是因為開發者違反了這個原則而導致的,所以自然能想到的,就是從變數的檢測、過濾、驗證下手,確保變數是開發者所預想的。

如果你的sql語句是類似where id=這種形式,資料庫裡所有的id都是數字,那麼就應該在sql被執行前,檢查確保變數id是int型別;如果是接受郵箱,那就應該檢查並嚴格確保變數一定是郵箱的格式,其他的型別比如日期、時間等也是乙個道理。總結起來:只要是有固定格式的變數,在sql語句執行前,應該嚴格按照固定格式去檢查,確保變數是我們預想的格式,這樣很大程度上可以避免sql注入攻擊。

對於無法確定固定格式的變數,一定要進行特殊符號過濾或轉義處理。以php為例,通常是採用addslashes函式,它會在指定的預定義字元前新增反斜槓轉義,這些預定義的字元是:單引號 (') 雙引號 (") 反斜槓 (\) null

相信大家都還對2023年爆出的csdn拖庫事件記憶猶新,這件事情導致csdn處在風口浪尖被大家痛罵的原因就在於他們竟然明文儲存使用者的密碼,這引發了科技界對使用者資訊保安尤其是密碼安全的強烈關注,我們在防範sql注入的發生的同時,也應該未雨綢繆,說不定下乙個被拖庫的就是你,誰知道呢。

在web開發中,傳統的加解密大致可以分為三種:

1、對稱加密:即加密方和解密方都使用相同的加密演算法和金鑰,這種方案的金鑰的儲存非常關鍵,因為演算法是公開的,而金鑰是保密的,一旦密匙洩露,黑客仍然可以輕易解密。常見的對稱加密演算法有:aesdes等。

2、非對稱加密:即使用不同的金鑰來進行加解密,金鑰被分為公鑰和私鑰,用私鑰加密的資料必須使用公鑰來解密,同樣用公鑰加密的資料必須用對應的私鑰來解密,常見的非對稱加密演算法有:rsa等。

3、不可逆加密:利用雜湊演算法使資料加密之後無法解密回原資料,這樣的雜湊演算法常用的有:md5sha-1等。

在我們上面登入系統的示例**中,$md5password = md5($password);從這句**可以看到採用了md5的不可逆加密演算法來儲存密碼,這也是多年來業界常用的密碼加密演算法,但是這仍然不安全。為什麼呢?

所以,我們有迫切的需求採用更好的方法對密碼資料進行不可逆加密,通常的做法是為每個使用者確定不同的密碼加鹽(salt)後,再混合使用者的真實密碼進行md5加密

python Web應用框架之Flask

pip install flask 以下是乙個簡單的flask應用 from flask import flask def hello world return hello world if name main 執行 python hello.py running on首先,我們匯入了 flask ...

Python Web 之Flask基礎(一)

flask 的基本使用 flask 1.0 文件 依賴 當安裝 flask 時,以下配套軟體會被自動安裝。可選依賴 以下配套軟體不會被自動安裝。如果安裝了,那麼 flask 會檢測到這些軟體。建立乙個專案資料夾,然後建立乙個虛擬環境。mkdir myproject cd myproject pyth...

python web框架之Tornado的簡單使用

python web框架有很多,比如常用的有django,flask等。今天主要介紹tornado tornado是乙個用python寫的相對簡單的 不設障礙的web伺服器架構,用以處理上萬的同時的連線口,讓實時的web服務通暢起來。雖然跟現在的一些用python寫的web架構相似,比如django...