19 смертных грехов, угрожающих безопасности программ. Майкл Ховард
Чтение книги онлайн.
Читать онлайн книгу 19 смертных грехов, угрожающих безопасности программ - Майкл Ховард страница 26
# Вывести данные
while (@row = $sth->fetchrow_array ) {
print "@row<br>";
}
$dbh->disconnect;
print "</body></html>";
exit;
Греховность Java
Еще один распространенный язык, Java. Подвержен внедрению SQL по той же схеме.
import java.*;
import java.sql.*;
...
public static boolean doQuery(String Id) {
Connection con = null;
try
{
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
con = DriverManager.getConnection("jdbc:microsoft:sqlserver: " +
"//localhost:1433", "sa", "$3cre+");
Statement st = con.createStatement();
ResultSet rs = st.executeQuery("SELECT ccnum FROM cust WHERE id=" +
Id);
while (rx.next()) {
// Полюбоваться на результаты запроса
}
rs.close();
st.close();
}
catch (SQLException e)
{
// Ой!
return false;
}
catch (ClassNotFoundException e)
{
// Не найден класс
return false;
}
finally
{
try
{
con.close();
} catch(SQLException e) {}
}
return true;
}
Греховность SQL
Подобный код встречается не так часто, но автор пару раз наталкивался на него в промышленных системах. Показанная ниже хранимая процедура просто принимает строку в качестве параметра и исполняет ее!
CREATE PROCEDURE dbo.doQuery(@query nchar(128))
AS
exec(@query)
RETURN
А вот следующий код распространен куда шире и не менее опасен:
CREATE PROCEDURE dbo.doQuery(@id nchar(128))
AS
DECLARE @query nchar(256)
SELECT @query = 'select ccnum from cust where id = ''' + @id + ''''
EXEC @query
RETURN
Здесь опасная конкатенация строк выполняется внутри процедуры. То есть вы по–прежнему совершаете постыдный грех, даже если процедура вызвана из корректного кода на языке высокого уровня.
Стоит поискать и другие операторы конкатенации, имеющиеся в SQL, а именно «+» и «||», а также функции CONCAT() и CONCATENATE().
Во всех этих примерах противник контролирует переменную Id. Важно всегда представлять себе, что именно контролирует атакующий, это поможет понять, есть реальная ошибка или нет. В данном случае противник может задать любое значение переменной Id, участвующей в запросе, и тем самым управлять видом строки запроса. Последствия могут оказаться катастрофическими.
Классическая атака состоит в том, чтобы видоизменить SQL–запрос, добавив лишние части и закомментарив «ненужные». Например, если противник контролирует переменную Id, то может задать в качестве ее значения строку 1 or 2>1 – – , тогда запрос примет такой вид:
SELECT ccnum FROM cust WHERE id=1 or 2>1 – –
Условие 2>1 истинно для всех строк таблицы, поэтому запрос возвращает все строки из таблицы cust, другими словами, номера всех кредитных карточек. Можно было