簡體   English   中英

在沒有預准備語句的情況下防止SQL注入(JDBC)

[英]Preventing SQL injection without prepared statements (JDBC)

我有一個數據庫日志追加器,每隔一段時間就會將可變數量的日志行插入到數據庫中。

我想以防止SQL注入的方式創建一個SQL語句,但不使用服務器端預處理語句(因為我在每個選擇中都有可變數量的行,緩存它們不會有幫助,但可能會損害性能) 。

我也喜歡准備好的語句的便利性,並且喜歡它們串聯連接。 有沒有像'客戶端准備好的聲明'?

聽起來你沒有對最簡單的解決方案 - 准備好的語句進行基准測試。 你說他們“可能會損害性能”,但在你測試之前,你真的不會知道。

肯定會先測試准備好的陳述。 即使它們確實會稍微妨礙性能,在您測試它們之前,您將無法知道您是否仍能達到所需的性能。

當你沒有嘗試過最明顯的解決方案時,為什么要花時間尋找替代解決方案呢?

如果您發現准備好的語句的執行計划緩存昂貴的,你可能會發現有調整或禁用的特定DB-方式。

不確定我是否正確理解你的問題。 PreparedStatement中有什么東西不適合您的需求嗎?

我認為該語句是否在服務器端緩存是數據庫驅動程序和您正在使用的特定數據庫的實現細節; 如果您的查詢/語句隨時間變化而不會產生影響 - 則不會使用緩存/編譯語句。

首先,Jon的答案是你應該采用最明顯的解決方案,直到性能被測量為一個問題,這當然是正確的方法。

我不認為您的性能問題是錯誤的。 我確實看到預編譯的復雜語句在性能規模上顯着失敗(在MS-SQL 2000上)。 原因是語句太復雜了,它根據參數有幾個潛在的執行路徑,但是編譯為一組參數鎖定了一個,而下一組參數太慢,而重新編譯會強制重新計算執行計划更適合不同的參數集。

但是這種擔憂是非常遙遠的,直到你在實踐中看到它。

這里的根本問題是參數轉義是特定於數據庫的,所以除非你的數據庫的JDBC驅動程序給你一些非標准的東西(非常不可能),你將不得不擁有一個不同的庫或不同的轉義機制,這個數據庫是非常具體的。

從您的問題的措辭來看,這聽起來並不像您的性能問題尚未找到(或開發)這樣的解決方案。

還應該注意的是,雖然JDBC驅動程序可能並非都是這樣,但從技術上講,根據規范,預編譯應該在PreparedStatement對象中緩存,如果你把它丟棄並且每次都得到一個新的PreparedStatement,它不應該實際上是緩存任何東西,所以整個問題可能是靜音的,需要針對您的特定JDBC驅動程序進行調查。

從規格:

可以預編譯帶有或不帶IN參數的SQL語句並將其存儲在PreparedStatement對象中。 然后,可以使用此對象多次有效地執行此語句。

使用常規預處理語句有什么問題,例如在以下偽代碼中:

DatabaseConnection connection;
PreparedStatement insertStatement = ...;

    ...

connection.beginTransaction();
for (Item item : items)
{
   insertStatement.setParameter(1, item);
   insertStatement.execute();
}
connection.commitTransaction();

智能數據庫實現將多​​個插入批處理到與數據庫服務器的一個通信交換中。

我想不出你不應該使用准備好的陳述的原因。 如果您使用連接池在J2EE服務器上運行此服務器,則服務器會保持連接打開,並且服務器會緩存您的訪問/執行計划。 這不是它緩存的數據!

如果您每次都關閉連接,那么您可能無法獲得任何性能。 但是你仍然可以獲得SQL注入預防

大多數java性能調優書都會告訴你相同的: Java性能調優

准備好的語句不關心客戶端或服務器端。

使用它們並刪除任何SQL字符串連接。 沒有一個理由不使用准備好的陳述。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM