Дэвид Лебланк - 19 смертных грехов, угрожающих безопасности программ
- Название:19 смертных грехов, угрожающих безопасности программ
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Дэвид Лебланк - 19 смертных грехов, угрожающих безопасности программ краткое содержание
Эта книга необходима всем разработчикам программного обеспечения, независимо от платформы, языка или вида приложений. В ней рассмотрены 19 грехов, угрожающих безопасности программ, и показано, как от них избавиться. Рассмотрены уязвимости на языках C/C++, C#, Java, Visual Basic, Visual Basic.NET, Perl, Python в операционных системах Windows, Unix, Linux, Mac OS, Novell Netware. Авторы издания, Майкл Ховард и Дэвид Лебланк, обучают программистов, как писать безопасный код в компании Microsoft. На различных примерах продемонстрированы как сами ошибки, так и способы их исправления и защиты от них. Если вы программист, то вам просто необходимо прочесть эту книгу.
Перевод: А. Слинкин
19 смертных грехов, угрожающих безопасности программ - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
Грех 4. Внедрение SQL–команд
В чем состоит грех
Уязвимость для внедрения SQL–команд (или просто «внедрение SQL») – это широко распространенный дефект, который может привести к компрометации машины и раскрытию секретных данных. А печальнее всего то, что от этой ошибки часто страдают приложения электронной коммерции и программы, обрабатывающие конфиденциальные данные и персональную информацию. Опыт авторов показывает, что многие приложения, работающие с базами данных, которые создавались для внутреннего использования или обмена информацией с партнерами по бизнесу, подвержены внедрению SQL.
Никогда не интересовались, как хакеры воруют номера кредитных карточек с Web–сайтов? Одним из двух способов: либо внедряя SQL, либо заходя через парадный вход, который вы распахиваете перед ними, открывая порт сервера базы данных (ТСР/1433 для Microsoft SQL Server, TCP/1521 для Oracle, TCP/523 для IBM/DB2 и TCP/3306 для MySQL) для доступа из Интернет и оставляя без изменения принимаемый по умолчанию пароль администратора базы данных.
Быть может, самая серьезная опасность, связанная с внедрением SQL, – это получение противником персональных или секретных данных. В некоторых странах, штатах и отраслях промышленности вас за это могут привлечь к суду. Например, в штате Калифорния можно сесть в тюрьму по закону о защите тайны личной жизни в сети, если из управляемой вами базы данных была похищена конфиденциальная или персональная информация. В Германии §9 DBSG (Федеральный закон о защите данных) требует, чтобы были предприняты должные организационные и технические меры для защиты систем, в которых хранится персональная информация. Не забывайте также о действующем в США Акте Сарбанеса–Оксли от 2002 года, и прежде всего о параграфе 404, который обязывает защищать данные, на основе которых формируется финансовая отчетность компании. Система, уязвимая для атак с внедрением SQL, очевидно, имеет неэффективные средства контроля доступа, а значит, не соответствует всем этим установлениям.
Напомним, что ущерб не ограничивается данными, хранящимися в базе. Внедрение SQL может скомпрометировать сам сервер, а не исключено, что и сеть целиком. Для противника скомпрометированный сервер базы данных – это лишь ступень к новым великим свершениям.
Подверженные греху языки
Все языки программирования, применяемые для организации интерфейса с базой данных, уязвимы! Но прежде всего это относится к таким языкам высокого уровня, как Perl, Python, Java, технологии «серверных страниц» (ASP, ASP.NET, JSP и PHP), С# и VB.NET. Иногда оказываются скомпрометированными также и языки низкого уровня, например библиотеки функций или классов, написанные на С или С++ (к примеру, библиотека c–tree компании FairCom или Microsoft Foundation Classes). Наконец, не свободен от греха и сам язык SQL.
Как происходит грехопадение
Самый распространенный вариант греха совсем прост – атакующий подсовывает приложению специально подготовленные данные, которые тот использует для построения SQL–предложения путем конкатенации строк. Это позволяет противнику изменить семантику запроса. Разработчики продолжают использовать конкатенацию, потому что не знают о существовании других, более безопасных методов. А если и знают, то не применяют их, так как, говоря откровенно, конкатенация – это так просто, а для вызова других функций еще подумать надо. Мы могли бы назвать таких программистов лентяями, но не станем.
Реже встречается другой вариант атаки, заключающийся в использовании хранимой процедуры, имя которой передается извне. А иногда приложение принимает параметр, конкатенирует его с именем процедуры и исполняет получившуюся строку.
Греховность С#
Вот классический пример внедрения SQL:
using System.Data;
using System.Data.SqlClient;
string ccnum = "None";
try {
SqlConnection sql = new SqlConnection(
@"data source=localhost;" +
"user id=sa;password=pAs$w0rd;");
sql.Open();
string sqlstring="SELECT ccnum" +
" FROM cust WHERE id=" + Id;
SqlCommand cmd = new SqlCommand(sqlstring,sql);
try {
ccnum = (string)cmd.ExecuteScalar();
} catch (SqlException se) {
Status = sqlstring + " failed\n\r";
foreach (SqlError e in se.Errors) {
Status += e.Message + "\n\r";
}
} catch (SqlException e) {
// Ой!
}
Ниже приведен по существу такой же код, но SQL–предложение строится с помощью замены подстроки, а не конкатенации. Это тоже ошибка.
using System.Data;
using System.Data.SqlClient;
string ccnum = "None";
try {
SqlConnection sql = new SqlConnection(
@"data source=localhost;" +
"user id=sa;password=pAs$w0rd;");
sql.Open();
string sqlstring="SELECT ccnum" +
" FROM cust WHERE id=%ID%";
String sqlstring2 = sqlstring.Replace("%ID", id);
SqlCommand cmd = new SqlCommand(sqlstring2,sql);
try {
ccnum = (string)cmd.ExecuteScalar();
} catch (SqlException se) {
Status = sqlstring + " failed\n\r";
foreach (SqlError e in se.Errors) {
Status += e.Message + "\n\r";
}
} catch (SqlException e) {
// Ой!
}
Греховность PHP
Вот та же классическая ошибка, но в программе на языке РНР, часто применяемом для доступа к базам данных.
Греховность Perl/CGI
И снова тот же дефект, но на этот раз в программе на достопочтенном Perl:
#!/usr/bin/perl
use DBI;
use CGI;
print CGI::header();
$cgi = new CGI;
$id = $cgi->param(\'id\');
$dbh = DBI->connect(\'DBI:mysql:Shipping:localhost\',
\'root\',
\'$3cre+\')
or print "Ошибка connect : $DBI::errstr";
$sql = "SELECT ccnum FROM cust WHERE id = " . $id;
$sth = $dbh->prepare($sql)
or print "Ошибка prepare : $DBI::errstr";
$sth->execute()
or print "Ошибка execute : $DBI::errstr";
# Вывести данные
while (@row = $sth->fetchrow_array ) {
print "@row
";
}
$dbh->disconnect; print "
";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)
Интервал:
Закладка: