簡體   English   中英

Java JDBC-如何執行語句嚴格只讀

[英]Java jdbc - how to execute a statement strictly read only

我的服務器應用程序幾乎在所有情況下都使用准備好的語句,以防止sql注入。 但是,有可能需要提供特殊的用戶來執行原始的SELECT查詢。

如何或多或少安全地確保查詢不會修改數據庫? 是否可以執行只讀查詢,或者是否有其他“安全”方式來確保沒有人嘗試任何SQL注入? (使用sqlite3,所以我不能使用任何特權)

非常感謝!

JDBC通過調用Connection.setReadOnly(true)支持只讀連接。 但是,javadoc說:

將此連接置於只讀模式,以提示驅動程序啟用數據庫優化

一些 JDBC驅動程序將強制執行只讀請求,其他一些 JDBC驅動程序將僅將其用於優化或忽略它。 我不知道sqlite3如何實現它。 您必須進行測試。

否則,您可以對SQL語句進行“簡單”解析,以確保它是單個有效的SELECT語句。

我不知道指定只讀的常規JBDC配置。 但是Sqlite確實具有特殊的數據庫打開模式,可以在與sqlite數據庫的連接中利用它。 例如。

Properties config = new Properties();
config.setProperty("open_mode", "1");  //1 == readonly
Connection conn = DriverManager.getConnection("jdbc:sqlite:sample.db", config);

信用: https : //stackoverflow.com/a/18092761/62344

FWIW 在此處可以看到所有受支持的打開模式。

如果使用某種工廠類來創建或返回數據庫連接,則可以將連接分別設置為只讀:

public Connection getReadOnlyConnection() {
    // Alternatively this could come from a connection pool:
    final Connection conn = DriverManager.getConnection("jdbc:sqlite:sample.db");
    conn.setReadOnly(true);
    return conn;
}

如果使用連接池,那么您可能還希望提供一種獲取可寫連接的方法:

public Connection getWriteableConnection() {
     final Connection conn = getPooledConnection(); // I'm assuming this method exists!
     conn.setReadOnly(false);
     return conn;
}

您也可以只提供一個getConnection(boolean readOnly)方法,只需將參數傳遞給setReadOnly(boolean)調用即可。 我個人更喜歡使用單獨的方法,因為這樣可以使您的意圖更加清晰。

或者,某些數據庫(例如Oracle)提供可以啟用的只讀模式。 SQLite不提供一個,但您可以通過簡單地將實際數據庫文件(包括目錄)設置為僅在文件系統本身上讀取來模擬它。

這樣做的另一種方式如下( 對於以下代碼,信用將變為死鎖 ):

public Connection getReadOnlyConnection() {
    SQLiteConfig config = new SQLiteConfig();
    config.setReadOnly(true);
    Connection conn = DriverManager.getConnection("jdbc:sqlite:sample.db",
            config.toProperties());
 }

暫無
暫無

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

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