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