Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

L3_NC

.pdf
Скачиваний:
17
Добавлен:
19.04.2015
Размер:
940.03 Кб
Скачать

Как бороться?: Stored Procedure

String custname = request.getParameter("customerName");

// This should REALLY be validated

try {

CallableStatement cs = connection.prepareCall(

"{call sp_getAccountBalance(?)}");

cs.setString(1, custname);

ResultSet results = cs.executeQuery();

//… result set handling

}catch (SQLException se) {

//… logging and error handling

}

© 2013 NetCracker Technology Corporation Confidential

21

Как бороться?: экранировать ВСЕ параметры

Encoder oe = new OracleEncoder();

String query = "SELECT user_id FROM user_data WHERE user_name = '"

+oe.encode( req.getParameter("userID")) + "' and user_password = '"

+oe.encode( req.getParameter("pwd")) +"'";

© 2013 NetCracker Technology Corporation Confidential

22

Литература по теме

http://www.unixwiz.net/techtips/sql-injection.html

http://www.slideshare.net/billkarwin/sql-injection-myths-and-fallacies

https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet

© 2013 NetCracker Technology Corporation Confidential

23

Что-то пошло не так…

одиночные запросы

© 2013 NetCracker Technology Corporation Confidential

24

Приём №1

Используйте оператор вывода для вывода запроса в том виде, в котором его получает СУБД.

System.out.println(sqlWithParams);

В Java для Prepared Statements в большинстве случаев нельзя получить SQL код

Encoderпослеoe подстановки= new OracleEncoder();параметров

StringЕслиqueryвсе-таки= "SELECTне повезлоuser: _id FROM user_data WHERE user_name = '"

Приём №2: настройте журналирование со стороны БД (google:”site:usertackoverflow.com %DB

+ oe.encode( req.getParameter("userID")) + "' and _password = '"

name% log query”)

+ oe.encode( req.getParameter("pwd")) +"'";

посмотрите на log4jdbc, DBAppender

напишите свой велосипед (http://stackoverflow.com/questions/2382532/how-can-i-get-the- sql-of-a-preparedstatement )

http://www.opennet.ru/docs/RUS/sql_error/

25

© 2013 NetCracker Technology Corporation Confidential

Приём №2

Используйте журналирование, если вам нужно определить какой именно запрос вызывает неправильное поведение вашего приложения.

Oracle http://docs.oracle.com/cd/E23943_01/bi.1111/e10541/logging.htm#CEGBIGIJ

Postgre SQL http://www.microhowto.info/howto/log_all_queries_to_a_postgresql_server.html

MySQL http://dev.mysql.com/doc/refman/5.1/en/query-log.html

%DB name% google:”site:stackoverflow.com %DB name% log query”)

© 2013 NetCracker Technology Corporation Confidential

26

Когда проблемый запрос найден…

1. Запустите запрос из консоли.

mysql> select count(*) as b from t3 order by b,a; +---+

| b | +---+ | 2 | | 2 | +---+

mysql> select count(*) as b from t3; +---+

| b | +---+ | 2 | +---+

1 row in set (0.01 sec)

Баг в MySQL 5.1.38

© 2013 NetCracker Technology Corporation Confidential

27

Когда проблемый запрос найден

Пробуйте изменить SQL таким образом, чтобы результат был правильным. Пользуйтесь поисковыми системами для нахождения workaround.

Посмотрите план выполнения.

mysql> select a.id as a_id, b.id from a a left join b b on a.id = b.a_id where a.id = 1;

+------

 

+------

 

+

| a_id | id

 

|

+------

 

+------

 

+

|

1

|

1

|

|

1 |

2 |

|

1

|

3

|

+------

 

+------

 

+

mysql> select a.id as a_id, count(distinct b.id) as cnt from a a left join b b on a.id = b.a_id where a.id = 1 group by a.id with rollup limit 100;

+------+-----+ | a_id | cnt |

+------

+

-----

+

|

1 |

8

|

| NULL |

8

|

+------

+-----

 

+

С индексом на b.id

Без индекса на b.id

http://bugs.mysql.com/bug.php?id=47650

+------+-----+ | a_id | cnt |

+------

+

-----+

|

1 |

3 |

| NULL |

3 |

+------

+-----

+

© 2013 NetCracker Technology Corporation Confidential

28

UPSERT + PostgreSQL

1.CREATE TABLE tbl( KEY int, val int);

2.INSERT INTO tbl(KEY,val)

3.SELECT DISTINCT(KEY), 0

4.

FROM unnest('{0,1,2,3,4,5}'::int[]) AS KEY

5.

WHERE KEY NOT IN (

6.

UPDATE tbl SET val = val+1

7.

WHERE KEY =

 

any('{0,1,2,3,4,5}'::int[])

8.

returning KEY );

ERROR: syntax error at OR near "tbl“ Строка 6: UPDATE tbl SET val = val+1

http://stackoverflow.com/questions/7191902/cannot-select-from-update-returning-clause- in-postgres

© 2013 NetCracker Technology Corporation Confidential

29

Когда проблемый запрос найден …

Если запрос DML – преобразуйте его в SELECT-запрос чтобы выяснить какие строки будут изменены.

mysql> create table t1(f1 int); mysql> create table t2(f2 int); mysql> insert into t1 values(1); Query OK, 1 row affected (0.01 sec)

mysql>

select * from t1;

+------

 

+

| f1

 

|

+------

 

+

|

1

|

+------

 

+

mysql> delete from t1, t2 using t1, t2; Query OK, 0 rows affected (0.00 sec)

© 2013 NetCracker Technology Corporation Confidential

30

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]