台灣最大程式設計社群網站
線上人數
1854
 
會員總數:243483
討論主題:188187
歡迎您免費加入會員
討論區列表 >> PHP >> SQL Injection和XSS防護函數詢問
[]  
[我要回覆]
1
回應主題 加入我的關注話題 檢舉此篇討論 將提問者加入個人黑名單
SQL Injection和XSS防護函數詢問
價值 : 50 QP  點閱數:516 回應數:14

樓主

迷路
高級專家
10036 134
6561 1660
發送站內信

捐贈 VP 給 迷路
最近打算升級對SQL Injection和XSS的防護
重寫了輸入字串檢查的函數
請各位大大幫我檢查看看是否有遺漏的部分


搜尋相關Tags的文章: [ SQL Injection ] , [ XSS ] ,
本篇文章發表於2018-04-10 15:42
別忘捐VP感謝幫助你的人 新手會員瞧一瞧
1樓
作者回應

迷路
捐贈 VP 給 迷路 檢舉此回應
搞笑了,編輯器居然會轉換字元@@?
從第6行到15行替換的字元都是 &#數字;
本篇文章回覆於2018-04-10 15:46
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
2樓
回應

浩瀚星空
捐贈 VP 給 浩瀚星空 檢舉此回應
其實~~~我搞不太懂你這樣做的用意在哪。
本篇文章回覆於2018-04-10 19:01
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
3樓
作者回應

迷路
捐贈 VP 給 迷路 檢舉此回應
把post和get進來的值先丟進這個函數處理一次
避免SQL Injection和XSS攻擊
另外有寫函數接收post和get,並在無值時設定預設值
有分接收變數和接收陣列,合計四個功能類似的函數
本篇文章回覆於2018-04-11 09:18
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
4樓
最有價值解答

可樂快跑
檢舉此回應
其實……你用pdo的prepare,在sql injection的部份就沒有必要做這種事了。
如果硬是要對特殊字元處理,或是防止xss攻擊的話,php已經有htmlspecialchars()這個函式了。
本篇文章回覆於2018-04-11 13:54
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
5樓
作者回應

迷路
捐贈 VP 給 迷路 檢舉此回應
新的網站已經換用PDO,用bindParam的方式將值帶入,對於SQL Injection的部分可以放下大部分的心
但是有些SQL無法靠bindParam來處理,例如將checkbox選取的值用IN ()的方式來搜尋
這個就沒辦法將()內的值用一個變數來處理,必須將每個值都設成一個變數
對於舊程式的改動太大,所以才會想說寫個函數來處理這部分的問題

htmlspecialchars()只對單雙引號、大小於和&進行處理
在看過 https://blog.davidh83110.com/%E8%B3%87%E8%A8%8A%E5%AE%89%E5%85%A8/%E9%A7%AD%E5%AE%A2%E6%8A%80%E8%A1%93/owasp%20top10/2016/10/10/xss.html
總覺得會不會不夠
本篇文章回覆於2018-04-11 15:30
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
6樓
不錯的參考

浩瀚星空
捐贈 VP 給 浩瀚星空 檢舉此回應
其實我現在只用pdo的防護作用。
再加上程式上的寫法應用。

因為一般來說注入的利用,是將單一欄位變成複合式欄位,或是跳胣的方式來處理。
所以,在針對where跟參數的處理只要做好如下處理就好了

1.不要傳送像是sql語法的參數值。這種的超容易被改被注入。

2.參數值最好是決定字串、陣列還是數值型態。(當然這非必要的,只是如果多這一層會更好)

3.不要傳送有&&、||、and、or等有關sql語法的字串相關。因為這樣就不好去下規則處理掉。
像是我曾經有開發過多重複合式條件的選單選項。需要決定用and還是or的情況。
我則是用代碼數值來傳送。不直接傳and跟or的字串。這樣,我在下參數規則會比較好下排除的動作。

4.如真不得已要傳送&%@!".....等這些可能語法上會用到的符號。在程式上我一定會將其做字串宣告處理。並透過htmlspecialchars之類的轉換函數處理。

5.簡單而言,只要你能在sql語法上,無法在單一參數中注入and or等條件式語法。再加上特規的引號轉碼處理。
大多數而言要注入就已經不是很簡單的事了。

ps:其實網路上很多防注入的處理方式。起源於要配合有關架構上參數傳送所造成的不得已的問題。
其實重點還是在於只要你的架構化不錯。幾乎是沒什麼機會可以讓人家可以用特殊的方式來改變你的sql的運作模式造成注入。

所以在一開頭,我就跟你說我搞不懂你這樣做的用意在哪。因為你根本防不了。
我為何會這樣說呢?
為了了解注入的問題,我也去學習了如何注入。也有去實驗了一些網站。
你還沒注意到還有一種技術是用代碼轉換的方式。
其原理就是他並沒用&&或是引號的方式做參數輸入。
但就是你在運行sql的時候,這些代碼會被轉換成引號或是特規代碼。
像這種的,你根本無法防。
(不過這招倒是只會在一些套裝程式上才有用就是了,畢竟轉換碼需要用另外一種方式處理)
本篇文章回覆於2018-04-12 14:10
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
7樓
回應

淺水員
檢舉此回應
但是有些SQL無法靠bindParam來處理,例如將checkbox選取的值用IN ()的方式來搜尋
這個就沒辦法將()內的值用一個變數來處理,必須將每個值都設成一個變數
對於舊程式的改動太大,所以才會想說寫個函數來處理這部分的問題
不知道是不是有相關範例或是更詳細的描述?
我是覺得這還是可以用PDO處理…
本篇文章回覆於2018-04-13 00:32
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
8樓
作者回應

迷路
捐贈 VP 給 迷路 檢舉此回應

$data1 能找到資料,但是 $data2 會是空的
本篇文章回覆於2018-04-13 11:19
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
9樓
回應

淺水員
檢舉此回應
只要不是把請求的參數字串直接放到SQL敘述
checkbox名稱既然是確定的
稍微組一下字串也無妨

本篇文章回覆於2018-04-13 15:16
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
10樓
回應

淺水員
檢舉此回應
上面的例子我沒把checkbox用陣列傳給php
(每個checkbox有不同的name)
如果原本的程式是使用相同的name,以陣列方式傳給php
那稍微修改一下即可:

總之,雖然有組字串
但是因為其來源($checkBoxList)是我們寫好的,而非來自於客戶端
就不用怕注入
本篇文章回覆於2018-04-13 15:44
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
11樓
回應

浩瀚星空
捐贈 VP 給 浩瀚星空 檢舉此回應
其實如#10的寫法,就是採用參數過濾化的方式。也就是利用5~8行的程式碼,將不正確的值給移除掉。
只是這招只適合少量及固定化參數的方式。

如果像是有text的話,就無法使用這一招了。畢竟輸入的值並不是固定化的。
大多數而言,還是需要處理引號跟去除值後做htmlspecialchars化等處理才會比較安全。

其實一般checkbox我還是會比較喜歡採用數值處理。
這樣就算人家想要搞怪。畢竟還是需要採用字串式的方式。
字串一但碰到數值化。就只能為0了。
本篇文章回覆於2018-04-13 19:02
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
12樓
不錯的參考

淺水員
檢舉此回應
下面的想法是用迴圈組出 IN 內需要的字串 s1
同時設定 execute 要用的 key=>value 物件 s2
再透過 pdo 執行 sql
本篇文章回覆於2018-04-14 02:26
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
13樓
作者回應

迷路
捐贈 VP 給 迷路 檢舉此回應
總結一下
資料庫注入部分用PDO+htmlspecialchars就夠了
這兩個的組合擋不了的,我自己寫也擋不了

條件式用到IN的部分
要另外寫函數去串SQL式和傳入值部分

XSS部分也是用htmlspecialchars就夠了?
本篇文章回覆於2018-04-16 16:41
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
14樓
不錯的參考

浩瀚星空
捐贈 VP 給 浩瀚星空 檢舉此回應
這樣的說法並不完全對,主要還是程式架構上的問題寫法居多了。
想靠規則來防是防不勝防。

不過透過轉換的想法是好的。
早10年前我的做法是會將get、post的值,透過一個自已寫的函數來過濾。
並另外做一個sql防注入的字串判斷。

基本上的條件其實也很單純。
用在set上的需要指定類型並轉換類型。
用在where上的就不能有引號跟連接詞(and or)出現

基本上,像用在in方面的。基本我會統一數值或統一字串。
且字串中,不會有空白跟引號。

其實只要你的設計架構好。大多數都可以不需要擔心注入的問題。

這種修正sql字串的做法,其實只是為了應付一些早期的不好程式的寫法來使用的。
但真的防護的地方很有限。
本篇文章回覆於2018-04-17 17:18
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
   
1

回覆
如要回應,請先登入.