[英]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.