2012-11-05 60 views
5

从安全的角度验证用事先准备好的声明,有没有之间的差异:在最安全的方式

stmt.setObject(1, theObject);

stmt.setString(1, theObject);

我知道,在这种情况下theObjectString但我感兴趣的是这个代码更普遍覆盖其他案件的一部分,如果输入验证的安全角度来看受到影响

回答

0

恕我直言

想知道

由于JDBC是围绕着数据库服务器很轻的包装(它使没有别的比生成SQL的数据库直接解释),我希望

stmt.setObject(1, theObject); 

要准确与

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

当数据库处理结果SQL并发现它是否适合它时,将发生“类型验证”。

+2

JDBC和ODBC是两种不同的技术,并且JDBC不是环绕ODBC(尽管存在桥接)。 – Paolo

+0

@Paolo我知道,当时我还没有表达出一种表达。我改变了它''数据库引擎'这是一个更好的选择。 – SJuan76

+0

但是,如果这是所有输入验证如何执行?没有正确的escapped字符串等? – Jim

1

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

然而,以这种方式传递一个任意的SQL字符串到数据库中的潜在问题 - 安全漏洞:没有,你用它来建立SQL字符串的任何参数的非常明智的验证,易于各种SQL插入攻击的类型。

谨防传递无类型nullsetObject()

+0

传递一个SQL字符串也是'setString'的问题吗? – Jim

+0

是的。在执行语句之前,您需要执行一些沙箱检查。 – aviad

+0

这听起来不正确。我已经读过,建议使用'PreparedStatements'来进行正确的输入。您是否说我*负责预先解析sql字符串? – Jim

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); 
    } 
} 
+0

如果这是如何完成的,输入验证是如何执行的? – Jim

+0

@Jim你想要什么样的验证?例如,sql注入只能使用字符串,但只有在它不正确“转义”的情况下。我希望这份工作能够正确执行jdbc提供程序:-D。在其他类型的演员阵容将崩溃。 – OkieOth

+0

检查@ aviad的答案。暗示其他方式 – Jim