当用户提供任意SQL标识符时,如何防止注入



我需要使用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。通过这种方式,您可以验证用户条目的格式是否正确,并且不包含任何可能影响您请求的特殊字符。

最新更新