6

从安全验证的角度来看,两者之间是否有区别:

stmt.setObject(1, theObject);

stmt.setString(1, theObject);?

我知道在这种情况下theObject是一个String,但我有兴趣使该代码的一部分更通用以涵盖其他情况,并且想知道输入验证的安全性是否受到影响

4

3 回答 3

1

使用 s 是可以的,setObject()因为 jdbc 会尝试对所有java.lang.*类型进行类型解析。

但是,以这种方式将任意 SQL 字符串传递给数据库存在潜在问题 -安全漏洞:如果没有对用于构建 SQL 字符串的任何参数进行非常明智的验证,您可能会受到各种类型的 SQL 插入攻击。

谨防将 untyped 传递nullsetObject()

于 2012-11-05T08:47:39.640 回答
0

恕我直言

鉴于 JDBC 是围绕数据库服务器的一个非常轻量级的包装器(除了为数据库生成 SQL 以直接解释之外,它几乎没有其他作用),我希望

stmt.setObject(1, theObject);

完全一样

stmt.setString(1, theObject == null ? "null" : theObject.toString())`;

当数据库处理生成的 SQL 并查找它是否适合它时,将发生“类型验证”。

于 2012-11-05T08:37:04.267 回答
0

答案似乎与提供者相关,并且取决于驱动程序的实现。我检查了当前 postgresql 驱动程序的来源,这两个调用是相等的。

如果驱动程序不知道类型,则会引发异常。

/** code from ./org/postgresql/jdbc2/AbstractJdbc2Statement.java */
public void setObject(int parameterIndex, Object x) throws SQLException
{
    checkClosed();
    if (x == null)
        setNull(parameterIndex, Types.OTHER);
    else if (x instanceof String)
        setString(parameterIndex, (String)x);
    else if (x instanceof BigDecimal)
        setBigDecimal(parameterIndex, (BigDecimal)x);
    else if (x instanceof Short)
        setShort(parameterIndex, ((Short)x).shortValue());
    else if (x instanceof Integer)
        setInt(parameterIndex, ((Integer)x).intValue());
    else if (x instanceof Long)
        setLong(parameterIndex, ((Long)x).longValue());
    else if (x instanceof Float)
        setFloat(parameterIndex, ((Float)x).floatValue());
    else if (x instanceof Double)
        setDouble(parameterIndex, ((Double)x).doubleValue());
    else if (x instanceof byte[])
        setBytes(parameterIndex, (byte[])x);
    else if (x instanceof java.sql.Date)
        setDate(parameterIndex, (java.sql.Date)x);
    else if (x instanceof Time)
        setTime(parameterIndex, (Time)x);
    else if (x instanceof Timestamp)
        setTimestamp(parameterIndex, (Timestamp)x);
    else if (x instanceof Boolean)
        setBoolean(parameterIndex, ((Boolean)x).booleanValue());
    else if (x instanceof Byte)
        setByte(parameterIndex, ((Byte)x).byteValue());
    else if (x instanceof Blob)
        setBlob(parameterIndex, (Blob)x);
    else if (x instanceof Clob)
        setClob(parameterIndex, (Clob)x);
    else if (x instanceof Array)
        setArray(parameterIndex, (Array)x);
    else if (x instanceof PGobject)
        setPGobject(parameterIndex, (PGobject)x);
    else if (x instanceof Character)
        setString(parameterIndex, ((Character)x).toString());
    else if (x instanceof Map)
        setMap(parameterIndex, (Map)x);
    else
    {
        // Can't infer a type.
        throw new PSQLException(GT.tr("Can''t infer the SQL type to use for an instance of {0}. Use setObject() with an explicit Types value to specify the type to use.", x.getClass().getName()), PSQLState.INVALID_PARAMETER_TYPE);
    }
}
于 2012-11-05T09:05:26.690 回答