sql注入的原理是什么,怎么預防sql注入


為什么會產生sql注入:

  主要原因,對用戶輸入的絕對信任,相信所有用戶的輸入都是可信的,沒有對用戶輸入的語句進行過濾或者篩選,直接放到sql語句中進行拼接,從而導致了sql注入的產生

  例如:

    <php?

      id = $_GET['id'];

      sql = "select * from tables where id=$id limit 0,1";

      .......

    ?>

  如果是正常的id等於數值之類,是沒有問題的,但是id如果被惡意用戶更改,我們原本的邏輯就會出現一系列的問題

  假如惡意用戶輸入的是 -1 union select version(),database()--+;

  直接將用戶輸入的id拼接上就會產生以下語句

  sql = "select * from tables where id=-1 union select version(),database()-- limit 0,1"(--表示的是數據庫注釋,+表示字符串的拼接)

  由於他將id設置為了-1,數據庫中不存在負值的id,所以第一個查詢會查詢到一個空的表,這樣數據庫會將union聯合查詢查詢到的sql結果,返回出來

  這樣,惡意用戶就會拿到我們數據庫的版本和數據庫的名字,要知道,在mysql5.0以上會存在一個information_schrma的數據庫,這個數據庫存放着所有的數據庫名,表名,字段名,我們所有數據就會被泄露,嚴重的,還能對我們的數據進行修改和刪除(堆疊查詢,將原來的sql閉合,這樣就可以直接對數據庫進行危險操作 比如 insert drop  有的數據庫或者中間件是不支持堆疊查詢,具體堆疊查詢(注入)就不再細說了)

sql注入的預防:

  sql注入的本質上還是對用戶輸入數據的絕對信任,當我們對用戶輸入的數據絕對不信任的時候,就可以預防sql注入

  1.輸入數據長度的限制

  2.關鍵字過濾:

    對每個參數的傳遞進行檢測,對其進行sql關鍵字過濾如(select insert where)          建議采用正則檢測和遞歸過濾

  3.對參數攜帶的特殊字符進行轉義和過濾:
    因為好多注入點都是在字符位置發生的,如果需要進行sql注入,就要先進性閉合的符號判斷(id='$id' 如果不進行引號的閉合,數據庫就會認為用戶輸入的所有參數為同一個字符串,這樣sql注入的參數就會被認為是無效的)這也是我們的防護手段之一                建議采用正則檢測和遞歸過濾

  4.預編譯防注入:預編譯防注入是目前最好的,最有效的防注入手段
    在數據庫進行預編譯的之后,sql語句已經會被數據庫編譯和優化了,並且運行數據庫以參數化的形式進行查詢,即使傳遞來的敏感字符也不會被執行,而是被當作參數處理

  5.不要直接顯示出錯誤的原因,最好指定一個錯誤的頁面,尤其是sql注入(即使存在注入,也要讓他去盲注)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM