来自

时间:2017-12-13 12:14:35

标签: javascript java tsql

我读到有关准备语句是避免sql注入数据库的好方法。 问题是客户想要一个安静的变量UI 他首先选择一个表,然后是一些由列和文本组成的约束。 所以基本上(天真的)最终产品看起来像这样:

Select * from %TABLENAME% where %ATTRIBUTENAME% = %VALUE%

现在的问题是如何确保安全?

当然,我可以构建一个prepare Statement解决方案,我提前为所有表创建语句,但这听起来像是一个非常愚蠢的想法,因为维护它的努力会很安静(客户很安静)几张桌子)。 知道如何以尽可能通用的安全方式解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

您应该将示例更改为

select * from %TABLENAME% where %ATTRIBUTENAME% = ?

这样至少VALUE不能用于SQL注入。然后,您可以针对数据库中的已知表和列对TABLENAMEATTRIBUTENAME进行验证。

请参阅运行时验证中可能使用的DatabaseMetaData.getColumns(...)。或者,您可能会使用有效的表/列保留在构建时生成的静态文件。

您可以在构建时为每个表/列组合生成Enum吗?我知道jOOQ从db模式生成这种构建时间java代码...也许它可以帮助吗?

例如

public enum TableColumn {
    CUSTOMER_NAME("customer", "name"), CUSTOMER_ID("customer", "id"),
    ORDER_ID("order", "id"), // etc etc

    String table;
    String column;

    public TableColumn(String table, String column) {
        // set values
    }
}

public List<Row> doSelect(TableColumn tc, Object value) {
    String sql = String.format("select * from %s where %s = ?", tc.table, tc.column);
    Connection con = getConnection();
    try {
        PreparedStatement ps = con.prepareStatement(sql);
        ps.setObject(1, value);
        ...