簡體   English   中英

動態生成DDL時如何防止SQL注入?

[英]How to prevent SQL injection when generating DDL dynamically?

目標:動態生成不受 SQL 注入影響的PreparedStatement

    // This is a bad method. SQL injection danger . But it works 
    private PreparedStatement generateSQLBad(Connection connection, String tableName, 
        String columnName, String columnType) throws SQLException {
        String sql = "create table " + tableName + " (" + columnName + " " + columnType + ")";
        PreparedStatement create = connection.prepareStatement(sql);
        return create;
    }

    // I tried this. But it didn't work  
    private PreparedStatement generateSQLGood(Connection connection, String tableName, 
        String columnName, String columnType) throws SQLException {
        String sql = "create table ? (? ?)";
        PreparedStatement create = connection.prepareStatement(sql);
        create.setString(1, tableName);
        create.setString(2, columnName);
        create.setString(3, columnType);
        return create;
    } 

如何動態生成PreparedStatement用戶可以選擇表名、列類型等並且沒有 SQL 注入的危險?

你不能用? 標識符的參數占位符(表名和列名)。 它們也不能用於 SQL 關鍵字,如數據類型。 准備查詢需要能夠驗證語法,並驗證您的表名等是否合法。 這必須在准備時完成,而不是在執行時完成。 SQL 不允許參數包含語法。 它們始終被視為標量值。 這就是他們如何防止 SQL 注入。

因此參數只能用於代替標量文字,如帶引號的字符串或日期,或數值。

動態標識符怎么辦? 正如評論所暗示的那樣,您能做的最好的事情就是過濾輸入,這樣它們就不會引入 SQL 注入。 在某種程度上,部分基於用戶輸入的動態 SQLSQL 注入。 您只需要以可控的方式允許它。

如果分隔標識符,所有 SQL 實現都允許您在表名中使用特殊字符。 標准 SQL 使用雙引號作為分隔符。 MySQL 使用反引號,Microsoft SQL Server 使用方括號。

關鍵是您可以通過這種方式創建看起來很奇怪的表名,例如包含空格、標點符號、國際字符或 SQL 保留字的表名。

CREATE TABLE "my table" ( col1 VARCHAR(20) );

CREATE TABLE "order" ( col1 VARCHAR(20) );

另請參閱我對https://stackoverflow.com/a/214344/20860 的回答

但是如果表名本身包含一個文字雙引號字符呢? 然后你必須轉義那個字符。 使用雙字符或反斜杠:

CREATE TABLE "Dwayne ""The Rock"" Johnson" ( col1 VARCHAR(20) );

CREATE TABLE "Dwayne \"The Rock\" Johnson" ( col1 VARCHAR(20) );

您也可以設計您的函數來檢查此類字符的動態表名稱,並將它們刪除或拋出異常。

但即使您通過仔細過濾輸入使語句安全,這也可能無法滿足 checkmarx 警告。 SQL 注入測試人員無法分析您的自定義代碼以確保它可靠地過濾輸入。

您可能只需要盡最大努力使動態 SQL 安全,因為知道 checkmarx 總是會抱怨它。 在您的代碼中編寫注釋,向閱讀您代碼的未來開發人員解釋您的安全措施。

還要編寫單元測試以確保危險的輸入導致安全的 DDL 語句或異常。

暫無
暫無

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

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