簡體   English   中英

私有查詢方法會增加SQL注入攻擊風險嗎?

[英]Does a private query method increase SQL injection attack risk?

我曾經有人指出,使用私有方法處理由單個類完成的所有查詢的查詢執行會增加SQL注入攻擊的風險。

此方法的示例可能如下所示(如下所示)。 我省略了一些細節,以免分散任何人的注意力。

如果您想談談實施,請隨時在評論中。 安全審查沒有評論該方法的內容,但主要是它不應該是自己的方法。

注意,queryText是從包含預准備語句的SQL文本的受保護靜態最終字符串生成的。 准備好的語句文本中的?是使用PreparedStatement的setString(或set whatever)方法設置的。 在預准備語句中設置的變量盡可能強類型地進入調用方法。

然后將queryText傳遞給私有方法。

    private ResultSet executeQuery(PreparedStatement stmt) throws SQLException {

    // Declare result set variable
    try{
        try{
            // execute statement and store in variable
        }
        catch(SQLException se){
            // log, close connection, do any special processing, rethrow se
        }

    }
    finally{
                    // This finally block is here to ensure the connection closes if
                    // some special processing (not shown) in the other try generates a runtime exception
        // close connection and statement properly
    }
    // return result set
}

推薦的替代方法是在執行查詢的每個方法中基本內聯相同的代碼。

我沒有將此發布到security.stackexchange.com,因為我認為它有資格作為特定的安全編程問題。

我認為沒有理由為什么將這個代碼(從私有方法)復制到許多類中會增加任何保護。 是嗎?

謝謝

如果此方法執行的查詢具有SQL注入所需的成分,那么無論private/public方法如何,它都會產生影響。

這個私有方法將由一些公共方法調用,該方法從用戶(或)數據庫獲取輸入。 如果該輸入是惡意的,則私有方法無法阻止它執行。

不要使用原始SQL字符串,總是更好地使用預准備語句。

擁有一個執行查詢的中心(不重復)位置是個主意。 從代碼可維護性和安全性角度來看都是如此。 為什么代碼可能多次出現問題? 這只意味着你必須多次維護它!

對我來說似乎很重要(以及通過編輯問題而改變的)是,應該盡可能地用它來執行手工構建的SQL字符串。

例如,您可以使用自定義枚舉替換任何String參數(您最初使用,但從那時PreparedStatement替換):

public enum SQLQuery {
  QUERY1("SELECT foo FROM BAR", 0),
  QUERY2("SELECT foo from BAR where baz = ?"; 1);

  private final String sql;
  private final int argumentCount;

  private SQLQuery(final String sql, final int argumentCount) {
    this.sql = sql;
    this.argumentCount = argumentCount;
  }

  public String getSQL() {
    return sql;
  }

  public int getArgumentCount() {
    return argumentCount;
  }
}

然后你可以像這樣編寫你的方法:

public ResultSet executeQuery(SQLQuery query, Object... arguments) {
  // implementation left as an exercise for the reader
}

通過這種方式,您可以非常確定您(或團隊中的任何其他人)不會意外地將自構建String傳遞給您的方法。

如果有必要,可以擴展此方法以處理不同的參數類型,但對於許多情況,使用setObject()工作正常。

為了提高模塊性,您可以從該枚舉中提取接口,並允許多個枚舉定義查詢(例如,如果項目中有單獨的模塊)。 但這有一個缺點,即惡意(或無能)的開發人員可以使用SQLQuery動態非枚舉實現來將他們手動構建的SQL字符串放入該方法中。

暫無
暫無

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

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