簡體   English   中英

帶表名的 PreparedStatement

[英]PreparedStatement with table name

我的代碼中有一個漏洞,我正在嘗試修復它。

為此,在 SQL 查詢中,我使用 PreparedStatements 安全地注入參數,如下所示:

String runQuery(String value) {

   String myReturn;
   String query = "select VALUE from " + tableName + " where config = ?";

   try(PreparedStatement ps = con.prepareStatement(query)){
      ps.setString(1, value);
      try(ResultSet rs = ps.executeQuery()) {
         if (rs.next()) {
            myReturn = rs.getString(1);
         } else {
            throw new BusinessException("noSQLResultSet");
         }
      }
   } catch (Exception sqlException) {
      throw new BusinessException("SQLException");
   }
   return myReturn;
}

我的問題是關於表tableName的名稱,我目前正在從位於服務器上的屬性文件中檢索它,但是從我看到的 PreparedStatements 中我無法注入表的名稱,因為它是不允許的。 如何在不連接查詢中的值的情況下以安全的方式指定表名?

表名不能用作PreparedStatement中的參數。 它必須是硬編碼的。

如我所見,您已經創建了包含 tableName 的查詢。 如果您從前端收到“或 1=1”之類的參數,則無法動態連接查詢和參數,因為您很容易受到 sql 注入的影響,但這里情況並非如此,因為您是單獨提供參數的。 無論如何,讓表名可配置聽起來有點奇怪。

沒有特別簡單的方法; 一種解決方案是將輸入列入白名單:如果它僅由字母和下划線組成,則可以。

請注意,您的異常處理非常糟糕,您正在丟棄所有有用的信息! 嘗試throw new BusinessException("uncaught", e); - 如果 BusinessException 是您的代碼,請確保添加該構造函數(您可以調用super(msg, cause); )。

我猜你想從你的屬性中獲取tableName的原因是你的模式是在一個 state 的通量(?)......在開發環境中並不罕見。 如果是這種情況,從您的屬性中獲取它不會引入漏洞,並且如果您使用的是Spring ,我相信您可以使用如下注釋:
@ConfigurationProperties(prefix = "schema.properties")
在您的 class 上,包括如下字段:
private String tableName;
在 class 中。 如果是這種情況,並且您在applications.properties文件(或特定於環境的等效項)中有一個字段,稱為:
schema.properties.tableName = myTableName
我認為你應該對 go 好。

暫無
暫無

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

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