我需要使用JDBC对PostgreSQL数据库运行LISTEN channel_name
,其中channel_name
由用户在web应用程序中提供。
channel_name
可以是任何PostgreSQL标识符。
我不相信我可以使用参数化,而且没有白名单可以检查。
如何允许用户安全地执行此操作?
我考虑过regexp,但我想知道是否有任何预先构建的东西,因为我不想犯错误。
当前代码(不支持带引号的标识符或非ascii字符):
public String checkIdentifier(String value) {
if (!value.matches("(?i)^[a-z_][a-z_0-9\$]{0,63}$")) {
throw new RuntimeException("Not a valid SQL identifier.");
}
return value;
}
注意,如果您不想在数据库imo中出现缺陷,那么您当前的方法是唯一合理的方法。
如果你坚持使用Postgres的内置方式,那就是使用quote_ident()
,如注释所示。但要小心,因为在这种情况下,"(?!: .
等输入将成为有效的标识符。psql
会处理得很好(希望如此),但键入这样的标识符可能会很痛苦。
也许您的ORM有后一个函数的包装器——如果没有,那么正如cHao所强调的,它是关于"
字符处理的。
如果它是一个表名,您也可以将它强制转换为regclass
,以确保标识符存在。
使用RegExp解析channel_name。通过这种方式,您可以验证用户条目的格式是否正确,并且不包含任何可能影响您请求的特殊字符。