防止sql注入漏洞
前言web漏洞之首莫過於sql了,不管使用哪種語言進行web後端開發,只要使用了關系型資料庫,可能都會遇到sql注入攻擊問題。那麼在Python web開發的過程中sql注入是怎麼出現的呢,又是怎麼去解決這個問題的?
當然,我這里並不想討論其他語言是如何避免sql注入的,網上關於php防注入的各種方法都有,Python的方法其實類似,這里我就舉例來說說。
起因漏洞產生的原因最常見的就是字元串拼接了,當然,sql注入並不只是拼接一種情況,還有像寬位元組注入,特殊字元轉義等等很多種,這里就說說最常見的字元串拼接,這也是初級程序員最容易犯的錯誤。
首先咱們定義一個類來處理mysql的操作
class Database:
hostname = '127.0.0.1'
user = 'root'
password = 'root'
db = 'pythontab'
charset = 'utf8'
def init(self):
self.connection = MySQLdb.connect(self.hostname, self.user, self.password, self.db, charset=self.charset)
self.cursor = self.connection.cursor()
def insert(self, query):
try:
self.cursor.execute(query)
self.connection.commit()
except Exception, e:
print e
self.connection.rollback()
def query(self, query):
cursor = self.connection.cursor(MySQLdb.cursors.DictCursor)
cursor.execute(query)
return cursor.fetchall()
def del(self):
self.connection.close()這個類有問題嗎?
答案是:有!
這個類是有缺陷的,很容易造成sql注入,下面就說說為何會產生sql注入。
為了驗證問題的真實性,這里就寫一個方法來調用上面的那個類裡面的方法,如果出現錯誤會直接拋出異常。
def test_query(testUrl):
mysql = Database()
try:
querySql = "SELECT * FROM `article` WHERE url='" + testUrl + "'"
chanels = mysql.query(querySql)
return chanels
except Exception, e:
print e這個方法非常簡單,一個最常見的select查詢語句,也使用了最簡單的字元串拼接組成sql語句,很明顯傳入的參數 testUrl 可控,要想進行注入測試,只需要在testUrl的值後面加上單引號即可進行sql注入測試,這個不多說,肯定是存在注入漏洞的,腳本跑一遍,看啥結果
(1064, "You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''t.tips''' at line 1")
回顯報錯,很眼熟的錯誤,這里我傳入的測試參數是
t.tips'
下面再說一種導致注入的情況,對上面的方法進行稍微修改後
def test_query(testUrl):
mysql = Database()
try:
querySql = ("SELECT * FROM `article` WHERE url='%s'" % testUrl)
chanels = mysql.query(querySql)
return chanels
except Exception, e:
print e這個方法裡面沒有直接使用字元串拼接,而是使用了 %s 來代替要傳入的參數,看起來是不是非常像預編譯的sql?那這種寫法能不能防止sql注入呢?測試一下便知道,回顯如下
(1064, "You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''t.tips''' at line 1")
和上面的測試結果一樣,所以這種方法也是不行的,而且這種方法並不是預編譯sql語句,那麼怎麼做才能防止sql注入呢?
解決兩種方案
1> 對傳入的參數進行編碼轉義
2> 使用Python的MySQLdb模塊自帶的方法
第一種方案其實在很多PHP的防注入方法裡面都有,對特殊字元進行轉義或者過濾。
第二種方案就是使用內部方法,類似於PHP裡面的PDO,這里對上面的資料庫類進行簡單的修改即可。
修改後的代碼
class Database:
hostname = '127.0.0.1'
user = 'root'
password = 'root'
db = 'pythontab'
charset = 'utf8'
def init(self):
self.connection = MySQLdb.connect(self.hostname, self.user, self.password, self.db, charset=self.charset)
self.cursor = self.connection.cursor()
def insert(self, query, params):
try:
self.cursor.execute(query, params)
self.connection.commit()
except Exception, e:
print e
self.connection.rollback()
def query(self, query, params):
cursor = self.connection.cursor(MySQLdb.cursors.DictCursor)
cursor.execute(query, params)
return cursor.fetchall()
def del(self):
self.connection.close()這里 execute 執行的時候傳入兩個參數,第一個是參數化的sql語句,第二個是對應的實際的參數值,函數內部會對傳入的參數值進行相應的處理防止sql注入,實際使用的方法如下
preUpdateSql = "UPDATE `article` SET title=%s,date=%s,mainbody=%s WHERE id=%s"
mysql.insert(preUpdateSql, [title, date, content, aid])
這樣就可以防止sql注入,傳入一個列表之後,MySQLdb模塊內部會將列表序列化成一個元組,然後進行escape操作。
❷ 如何實現php的安全最大化怎樣避免sql注入漏洞和xss跨站腳本攻擊漏洞
使用php安全模式
伺服器要做好管理,賬號許可權是否合理。
假定所有用戶的輸入都是「惡意」的,防止XSS攻擊,譬如:對用戶的輸入輸出做好必要的過濾
防止CSRF,表單設置隱藏域,post一個隨機字元串到後台,可以有效防止跨站請求偽造。
防禦SQL注入。
避免SQL注入漏洞
1.使用預編譯語句
2.使用安全的存儲過程
3.檢查輸入數據的數據類型
4.從資料庫自身的角度考慮,應該使用最小許可權原則,不可使用root或dbowner的身份連接資料庫。若多個應用使用同一個資料庫,也應該為資料庫分配不同的賬戶。web應用使用的資料庫賬戶,不應該有創建自定義函數,操作本地文件的許可權。
避免XSS跨站腳本攻擊
1.假定所有用戶輸入都是「邪惡」的
2.考慮周全的正則表達式
3.為cookie設置HttpOnly,防止cookie劫持
4.外部js不一定可靠
5.出去不必要的HTML注釋
6. 針對非法的HTML代碼包括單雙引號等,使用htmlspecialchars()函數。
❸ 如何防範SQL注入漏洞及檢測
SQL注入漏洞攻擊的防範方法有很多種,現階段總結起來有以下方法:
(1)數據有效性校驗。如果一個輸入框只可能包括數字,那麼要通過校驗確保用戶輸入的都是數字。如果可以接受字母,那就要檢查是不是存在不可接受的字元,最好的方法是增加字元復雜度自動驗證功能。確保應用程序要檢查以下字元:分號、等號、破折號、括弧以及SQL關鍵字。另外限製表單數據輸入和查詢字元串輸入的長度也是一個好方法。如果用戶的登錄名最多隻有10個字元,那麼不要認可表單中輸入10個以上的字元,這將大大增加攻擊者在SQL命令中插入有害代碼的難度。
(2)封裝數據信息。對客戶端提交的數據進行封裝,不要將數據直接存入cookie中,方法就是在編程的代碼中,插入session、if、try、else,這樣可以有效地防止攻擊者獲取cookie中的重要信息。
(3)去除代碼中的敏感信息。將在代碼中存在的用戶名、口令信息等敏感欄位刪除,替換成輸入框。
SQL=" select from users where username = 』admin』and password= 』1234567』 "
如:這樣顯然會暴露管理員的用戶名、口令信息。可以將其修改成:
SQL= " select * from users where username='" +Txtuser.Text + "' and userpwd='" + Textpwd.Text + "'"
這樣就安全了很多,入侵者也是不會輕易的就獲取到用戶名、口令信息。
(4)替換或刪除單引號。使用雙引號替換掉所有用戶輸入的單引號,這個簡單的預防措施將在很大程度上預防SQL注入漏洞攻擊,單引號時常會無法約束插入數據的Value,可能給予輸入者不必要的許可權。用雙引號替換掉單引號可以使大部分SQL注入漏洞攻擊失敗。 如:
「select* from users where username='" + admin + "' and userpwd='" + 1234567+ "'」
顯然會得到與
「select * from users where username='admin' and password= '1234567'」
相同的結果。
(5)指定錯誤返回頁面。攻擊者有時從客戶端嘗試提交有害代碼和攻擊字元串,根據Web Service給出的錯誤提示信息來收集程序及伺服器的信息,從而獲取想得到的資料。應在Web Service中指定一個不包含任何信息的錯誤提示頁面。
(6)限制SQL字元串連接的配置文件。使用SQL變數,因為變數不是可以執行的腳本,即在Web頁面中將連接資料庫的SQL字元串替換成指定的Value,然後將Web.config文件進行加密,拒絕訪問。
(7)設置Web目錄的訪問許可權。將虛擬站點的文件目錄禁止遊客用戶(如:Guest用戶等)訪問,將User用戶許可權修改成只讀許可權,切勿將管理許可權的用戶添加到訪問列表。
(8)最小服務原則。Web伺服器應以最小許可權進行配置,只提供Web服務,這樣可以有效地阻止系統的危險命令,如ftp、cmd、vbscript等。
(9)鑒別信息加密存儲。將保存在資料庫users表中的用戶名、口令信息以密文形式保存,也可以對users表進行加密處理,這樣可以大大增加對鑒別信息訪問的安全級別。
(10)用戶許可權分離。應盡可能的禁止或刪除資料庫中sa許可權用戶的訪問,對不同的資料庫劃分不同的用戶許可權,這樣不同的用戶只能對授權給自己的資料庫執行查詢、插入、更新、刪除操作,就可以防止不同用戶對非授權的資料庫進行訪問。
❹ SpringBoot 防止SQL注入、XSS攻擊、CSRF/CROS惡意訪問
一、SQL 注入問題
SQL 注入即是指 web 應用程序對用戶輸入數據的合法性沒有判斷或過濾不嚴,攻擊者可以在 web 應用程序中事先定義好的查詢語句的結尾上添加額外的 SQL 語句,在管理員不知情的情況下實現非法操作,以此來實現欺騙資料庫伺服器執行非授權的任意查詢,從而進一步得到相應的數據信息。
簡單來說,就是將大部分 SQL 語句當參數傳入系統中,從而獲取系統中的數據。下面簡單舉例說明
系統中有這樣一條信息 SQL 語句執行,分頁查詢所有用戶,每頁查詢 20 條,並且根據指定欄位進行排序,也就是說排序欄位也是參數傳遞過來的
SQL 注入問題分析:
這樣很簡單的一句話 SQL,就可以把系統搞炸掉,這種方式可以實現刪庫跑路
以上語句會把整個 test 資料庫所有內容都刪掉
盡量用預編譯機制,少用字元串拼接的方式傳參,它是 sql 注入問題的根源。
有些特殊字元,比如:%作為 like 語句中的參數時,要對其進行轉義處理。
需要對所有的異常情況進行捕獲,切記介面直接返回異常信息,因為有些異常信息中包含了 sql 信息,包括:庫名,表名,欄位名等。攻擊者拿著這些信息,就能通過 sql 注入隨心所欲地攻擊你的資料庫了。目前比較主流的做法是,有個專門的網關服務,它統一暴露對外介面。用戶請求介面時先經過它,再由它將請求轉發給業務服務。這樣做的好處是:能統一封裝返回數據的返回體,並且如果出現異常,能返回統一的異常信息,隱藏敏感信息。此外還能做限流和許可權控制。
使用 sqlMap 等待代碼檢測工具,它能檢測 sql 注入漏洞。
需要對資料庫 sql 的執行情況進行監控,有異常情況,及時郵件或簡訊提醒。
對生產環境的資料庫建立單獨的賬號,只分配 DML 相關許可權,且不能訪問系統表。切勿在程序中直接使用管理員賬號。
建立代碼 review 機制,能找出部分隱藏的問題,提升代碼質量。
對於不能使用預編譯傳參時,要麼開啟 druid 的 filter 防火牆,要麼自己寫代碼邏輯過濾掉所有可能的注入關鍵字。
XSS 攻擊通常指的是通過利用網頁開發時留下的漏洞,通過巧妙的方法注入惡意指令代碼到網頁,使用戶載入並執行攻擊者惡意製造的網頁程序。這些惡意網頁程序通常是 JavaScript,但實際上也可以包括 Java、 VBScript、ActiveX、 Flash 或者甚至是普通的 HTML。攻擊成功後,攻擊者可能得到包括但不限於更高的許可權(如執行一些操作)、私密網頁內容、會話和 cookie 等各種內容。
通常情況下,被用來盜用 Cookie、破壞頁面結構、重定向到其他網站等
對用戶輸入的表單信息進行檢測過濾
CSRF - Cross-Site Request Forgery - 跨站請求偽造:
攻擊可以在受害者毫不知情的情況下以受害者名義偽造請求發送給受攻擊站點,從而在未授權的情況下執行在許可權保護之下的操作,CORS - Cross Origin Resourse-Sharing - 跨站資源共享,惡意訪問內網敏感資源。
有效的解決辦法是通過多種條件屏蔽掉非法的請求,例如 HTTP 頭、參數等:
防止大規模的惡意請求,niginx 反向代理可以配置請求頻率,對 ip 做限制。nginx 可以很方便地做訪問控制,特別是一些偶發性的大量惡意請求,需要屏蔽處理。
屏蔽 ip 地址
屏蔽 user-agent
屏蔽代理 ip
有兩種情形會需要屏蔽代理 ip:一是代理 ip 訪問,二是負載均衡(real-ip 請求負載均衡伺服器,再代理給後端 server)
創建 包裝器,這是實現 XSS 過濾的關鍵,在其內重寫了 getParameter,getParameterValues,getHeader 等方法,對 http 請求內的參數進行了過濾