熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

Java開發中容易產生Sql注入的原因以及避免方式

2013-11-23 18:53:29  來源: Java核心技術 
    注入 攻 擊 是利用是指利用 設計 上的漏洞在目 標 服 務 器上運行 Sql語 句以及 進 行其他方式的 攻 擊
    動態 生成 Sql語 句 時 沒有 對 用 戶輸 入的數據 進 行 驗證 是 Sql注入 攻 擊 得逞的主要原因
    對 於 JDBC而言 SQL注入 攻 擊 只 對 Statement有效 對 PreparedStatement 是無效的 這 是因 為 PreparedStatement 不允 許在不同的插入 時間 改 變查詢 的 邏輯結 構
    如 驗證 用 戶 是否存在的 SQL語 句 為
    用 戶 名 and pswd=密 碼
    如果在 用 戶 名字段 中 輸 入
    或是在 密 碼 字段 中 輸 入
    將 繞過驗證 但 這種 手段只 對 只 對 Statement有效 對 PreparedStatement 無效
    相 對 Statement有以下 優 點
    防注入 攻 擊
    多次運行速度快
    防止 數據 庫緩 沖區溢出
    代 碼 的可 讀 性可 維護 性好
    這 四點使得 PreparedStatement 成 為訪問 數據 庫 的 語 句 對 象的首 選 缺點是靈活性不 夠 好有些 場 合 還 是必 須 使用Statement
    網上抄的
    是預編譯的對於批量處理可以大大提高效率 也叫JDBC存儲過程
    使用 Statement 對象在對數據庫只執行一次性存取的時侯用 Statement 對象進行處理PreparedStatement 對象的開銷比Statement大對於一次性操作並不會帶來額外的好處
    每次執行sql語句相關數據庫都要執行sql語句的編譯preparedstatement是預編譯得preparedstatement支持批處理
    ′Colombian′
    片斷和片斷的區別在於後者使用了PreparedStatement對象而前者是普通的Statement對象 PreparedStatement對象不僅包含了SQL語句而且大多數情況下這個語句已經被預編譯過因而當其執行時只需DBMS運行SQL語句 而不必先編譯當你需要執行Statement對象多次的時候PreparedStatement對象將會大大降低運行時間當然也加快了訪問數據庫的 速度
    這種轉換也給你帶來很大的便利不必重復SQL語句的句法而只需更改其中變量的值便可重新執行SQL語句選擇PreparedStatement對 象與否在於相同句法的SQL語句是否執行了多次而且兩次之間的差別僅僅是變量的不同如果僅僅執行了一次的話它應該和普通的對象毫無差異體現不出 它預編譯的優越性
    執行許多SQL語句的JDBC程序產生大量的Statement和PreparedStatement對象通常認為 PreparedStatement對象比Statement對象更有效特別是如果帶有不同參數的同一SQL語句被多次執行的時候 PreparedStatement對象允許數據庫預編譯SQL語句這樣在隨後的運行中可以節省時間並增加代碼的可讀性
    然而在Oracle環境中開發人員實際上有更大的靈活性當使用Statement或PreparedStatement對象時Oracle數據庫 會緩存SQL語句以便以後使用在一些情況下由於驅動器自身需要額外的處理和在Java應用程序和Oracle服務器間增加的網絡活動執行 PreparedStatement對象實際上會花更長的時間
    然而除了緩沖的問題之外至少還有一個更好的原因使我們在企業應用程序中更喜歡使用PreparedStatement對象那就是安全性傳遞給 PreparedStatement對象的參數可以被強制進行類型轉換使開發人員可以確保在插入或查詢數據時與底層的數據庫格式匹配
    當處理公共Web站點上的用戶傳來的數據的時候安全性的問題就變得極為重要傳遞給PreparedStatement的字符串參數會自動被驅動器忽 略最簡單的情況下這就意味著當你的程序試著將字符串DAngelo插入到VARCHAR中時該語句將不會識別第一個從而導致悲慘的 失敗幾乎很少有必要創建你自己的字符串忽略代碼
    在Web環境中有惡意的用戶會利用那些設計不完善的不能正確處理字符串的應用程序特別是在公共Web站點上在沒有首先通過 PreparedStatement對象處理的情況下所有的用戶輸入都不應該傳遞給SQL語句此外在用戶有機會修改SQL語句的地方如HTML的 隱藏區域或一個查詢字符串上SQL語句都不應該被顯示出來
    在執行SQL命令時我們有二種選擇可以使用PreparedStatement對象也可以使用Statement對象無論多少次地使用同一個 SQL命令PreparedStatement都只對它解析和編譯一次當使用Statement對象時每次執行一個SQL命令時都會對它進行解析 和編譯
    第一
    會先初始化SQL先把這個SQL提交到數據庫中進行預處理多次使用可提高效率
    不會初始化沒有預處理沒次都是從開始執行
    第二
    可以替換變量
    在SQL語句中可以包含?可以用
    可以把?替換成變量
    而Statement只能用
    來實現
    第三
    會先初始化SQL先把這個SQL提交到數據庫中進行預處理多次使用可提高效率
    不會初始化沒有預處理沒次都是從開始執行
From:http://tw.wingwit.com/Article/program/Java/hx/201311/25937.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.