2012-03-29 5 views
3

Мы с учителем обсудили возможность ввода SQL в подготовленный оператор. Я понимаю, что обычно вы не могли, но профессор настаивает на использовании sql concatenation вместо использования (?).SQL-инъекции и подготовленные операторы

Теперь я пытаюсь сломать свой код, но мне не повезло.

public Users getUserByUsername(String username) throws SQLException { 
    StringBuffer sql = new StringBuffer(); 

    sql.append("select * from users as u, user_type_lookup as l, user_types as t "); 
    sql.append("where u.users_id=l.user_id and l.type_id=t.user_types_id and u.username='"); 
    sql.append(username); 
    sql.append("';"); 

    System.out.println(sql.toString()); 

    PreparedStatement ps = conn.prepareStatement(sql.toString()); 
    ResultSet rs = ps.executeQuery(sql.toString()); 

    if (!rs.next()) { 
     return null; 
    } 

    String password = rs.getString("password"); 
    String type = rs.getString("description"); 
    int id = rs.getInt("users_id"); 
    int incorrect_logins = rs.getInt("incorrect_logins"); 
    Time wait_time = rs.getTime("wait_time"); 

    Users u = new Users(id, username, password, type, incorrect_logins, 
      wait_time); 
    return u; 
} 

Вставки Я пробовал:

string: '; DELETE FROM users WHERE 1 or users_id = ' 
string: ';delete from users where username<>' 
//The only one that worked  
string: stan' or 'a'<>'b 

вывода SQL (приводит к ошибке Java):

select * from users as u, user_type_lookup as l, user_types as t where u.users_id=l.user_id and l.type_id=t.user_types_id and u.username=''; DELETE FROM users WHERE 1 or users_id = ''; 

выход SQL (работает по назначению):

select * from users as u, user_type_lookup as l, user_types as t where u.users_id=l.user_id and l.type_id=t.user_types_id and u.username='stan'; 

Сообщение об ошибке:

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your  
SQL syntax; check the manual that corresponds to your MySQL server version for the 
right syntax to use near 'DELETE FROM users WHERE 1 or users_id = ''' at line 1 

сервер: Tomcat 7

База данных: MySQL

IDE: Eclipse,

Язык: Java

Так, пожалуйста, помогите мне сломать мой код!

+0

Подготовленные утверждения среди других, как правило, ускользают от ценностей. Если значения уже экранированы, следует использовать конкатенацию. – kirilloid

+0

Хотя я думаю, что это хороший вопрос с точки зрения «Может ли подготовленные утверждения подвергаться атаке с помощью SQL Injection» ... на самом деле это не так написано ... вы можете сделать это скорее как вопрос, так что ответ могут быть предоставлены. – scunliffe

+2

Даже если вы смогли ввести SQL в этот оператор, вы сделали это благодаря тому, как вы написали свой код. Это * не * подготовленное заявление. – NullUserException

ответ

4

Вы не можете добавить отдельное заявление внутри SQL подготавливаемого-заявление, но вы можете разбить его, например:

  • использованием ' OR 'x' = 'x в качестве имени пользователя (так что запрос будет сделать картезианское соединение между всеми пользователями и отображать типы между ними); это сильно повредит производительности, если users и user_type_lookup являются большими столами и станут отличным началом атаки на отказ в обслуживании.
  • с использованием ' OR (SELECT stored_procedure_that_deletes_things()) = 1 (так что запрос вызовет хранимую процедуру, которая имеет вредные эффекты).
Смежные вопросы