2012-11-05 23 views
5

Từ góc độ xác nhận an ninh, có sự khác biệt giữa:Sử dụng tuyên bố chuẩn bị theo cách an toàn nhất

stmt.setObject(1, theObject);

stmt.setString(1, theObject);?

Tôi biết rằng trong trường hợp này theObject là một String nhưng tôi quan tâm trong việc đưa ra một phần của mã này tổng quát hơn để trang trải các trường hợp khác và đã tự hỏi nếu quan điểm an ninh của xác nhận đầu vào bị ảnh hưởng

Trả lời

0

IMHO

cho rằng JDBC là một wrapper rất nhẹ xung quanh máy chủ cơ sở dữ liệu (nó làm chút gì khác hơn tạo ra SQL cho DB để trực tiếp giải thích), tôi mong đợi

stmt.setObject(1, theObject); 

để được chính xác giống với

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

"Xác thực loại" sẽ xảy ra khi cơ sở dữ liệu xử lý SQL kết quả và tìm xem nó có phù hợp không.

+2

JDBC và ODBC là hai công nghệ khác nhau và JDBC không quấn quanh ODBC (mặc dù có cầu). – Paolo

+0

@Paolo Tôi biết, tôi đã thiếu một biểu hiện vào thời điểm đó. Tôi đã thay đổi nó cho 'cơ sở dữ liệu' mà là một phù hợp hơn. – SJuan76

+0

Nhưng nếu điều này là tất cả làm thế nào là xác thực đầu vào thực thi? Không đúng cách escapped dây vv? – Jim

1

Bạn có thể sử dụng s setObject() vì jdbc sẽ cố gắng thực hiện độ phân giải loại cho tất cả các loại java.lang.*.

Tuy nhiên, có vấn đề tiềm tàng khi truyền chuỗi SQL tùy ý đến cơ sở dữ liệu theo cách này - Sơ hở bảo mật: không xác thực rất hợp lý bất kỳ tham số nào bạn sử dụng để xây dựng chuỗi SQL, bạn có trách nhiệm các loại tấn công chèn SQL.

Hãy coi chừng đi qua untyped null để setObject()

+0

Việc truyền chuỗi SQL có phải là một vấn đề đối với 'setString' không? – Jim

+0

có. Bạn cần phải thực hiện kiểm tra hộp cát trước khi thực hiện câu lệnh. – aviad

+0

Điều này không đúng. Tôi đã đọc rằng bạn nên sử dụng 'PreparedStatements' để nhập đúng. Bạn đang nói * Tôi * chịu trách nhiệm" phân tích cú pháp "chuỗi sql trước? – Jim

0

Câu trả lời dường như được cung cấp dịch vụ liên quan và phụ thuộc tình hình thực hiện của các tài xế. Tôi kiểm tra nguồn của trình điều khiển postgresql hiện tại và có hai cuộc gọi bằng nhau.

Nếu trình điều khiển không biết loại ngoại lệ được ném.

/** 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

Nếu đây là cách nó đang được thực hiện, làm thế nào là xác nhận đầu vào thực thi? – Jim

+0

@Jim Bạn muốn loại xác thực nào khác? Ví dụ, tiêm sql chỉ có thể làm việc với các chuỗi nhưng chỉ khi nó không đúng "thoát". Tôi hy vọng công việc này làm đúng nhà cung cấp jdbc :-D. Trên các loại khác, dàn diễn viên sẽ gặp sự cố. – OkieOth

+0

Kiểm tra câu trả lời của @ aviad. Có vẻ như ngụ ý cách khác – Jim

Các vấn đề liên quan