gpt4 book ai didi

function - JDBC Postgres 存储函数调用返回 setof 'myType'

转载 作者:行者123 更新时间:2023-11-29 12:22:31 25 4
gpt4 key购买 nike

我正在尝试保护我的数据库免受 SQL 注入(inject)攻击。我有许多返回 SETOF 我预定义数据类型的存储函数。例如:

create type userLoginUserIdPasswordReturnType as
(
userId integer, -- user.id
password text
);

CREATE OR REPLACE FUNCTION "user_login_get_id_password"(usernameIn text)
returns setof userLoginUserIdPasswordReturnType as
$$
declare
sql text;
begin
sql = 'select id, cryptpwd from "user" where username = ' || usernameIn ||';';
return query execute sql;
end;
$$ language 'plpgsql';

我现在想从我的 Java 前端调用这些存储过程。据我所知,使用 CallableStatement 对于 SQL 注入(inject)更安全。这是我到目前为止所拥有的:

public ArrayList<String> userLoginGetIdPassword(String username){
ArrayList<String> result = new ArrayList<String>();
try{
String commandText = "{call user_login_get_id_password(?)}";
this.cstmt = this.myConnection.prepareCall(commandText);
this.cstmt.setObject(1, username);
// this.rs = this.cstmt.execute();
this.rs = cstmt.executeQuery();
while (this.rs.next()){
result.add(this.rs.getString(1));
}
} catch (SQLException e){
System.out.println("SQL Exception: ");
e.printStackTrace();
}
return result;
}

如果我尝试使用 execute() 方法,它会要求我将 ResultSet rs 设置为 bool 值。如果按原样运行 (executeQuery()),则只能在 ResultSet 中看到 returnType 的第一个字段 (userId)。

如果我这样调用存储过程:

public ArrayList<String> userLoginGetIdPassword(String username){
ArrayList<String> result = new ArrayList<String>();
try{
String query = "select \"user_login_get_id_password\"('" + username + "');";
System.out.println(query);
this.stmt = this.myConnection.createStatement();
this.rs = this.stmt.executeQuery(query);
while (this.rs.next()){
result.add(this.rs.getString(1));
}
} catch (SQLException e){
System.out.println("SQL Exception: ");
e.printStackTrace();
}
return result;
}

我得到了正确的数据。

此外,如果有任何进一步的提示可以保护我的数据库免受 SQL 注入(inject)攻击,请指出。我已经创建了应用程序将使用的特定 Postgres 角色,并实现了连接池 (c3p0) 以连接到我的数据库——应用程序将在本地网络上运行。我正在验证来自不同 Java Swing 组件的用户输入以避免 SQL 注入(inject)攻击(注释 --、分号、* 和其他 SQL 命令,如 DELETE)。

欢迎任何意见。

谢谢。

最佳答案

首先,PostgreSQL 不支持 call 命令,所以这就是您的第一种方法失败的原因。

在第二种方法中,您将遇到两个问题。首先是SQL注入(inject)。使用标准绑定(bind)方法将解决这个问题。你的第二个问题是你将很难从你调用它的函数中解析回数据。

更好的方法是类似

SELECT * FROM user_login_get_id_password(?)

但是请注意,sql 注入(inject)可能在您的函数内。在一定程度上您可以避免EXECUTE 来保护您。如果必须使用执行,请将查询字符串更改为:

sql =  'select id, cryptpwd from "user" where username = ' || quote_literal(usernameIn);

执行查询中不需要终止分号。它会自动终止。不过,您确实需要调用 quote_literal(如果引用表/列名称,请使用 quote_ident())。

关于function - JDBC Postgres 存储函数调用返回 setof 'myType',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11257110/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com