我需要使用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;
}

最佳答案

为了说明这一点,如果您不想让数据库中有疣,那么您当前的方法是唯一明智的方法。
如果您坚持使用Postgres,那么内置的Postgres方法就是使用注释中指出的quote_ident()。但要小心,因为在这种情况下,"(?!: .等输入将成为有效的标识符。psql会处理得很好(希望如此),但像这样键入标识符可能会很麻烦。
也许您的ORM有后一个函数的包装器——如果没有,正如cHao所强调的,它是关于"字符处理的。
如果它是一个表名,您也可以将其转换为regclass,以确保标识符存在。

关于postgresql - 用户提供任意SQL标识符时如何防止注入(inject)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23315270/

10-15 19:38