Скачать книгу

В Германии §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

Скачать книгу