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

= $HTTP_GET_VARS["id"];

      $qry = "SELECT ccnum FROM cust WHERE id = %$id%";

      $result = mysql_query($qry,$db);

      if ($result) {

      echo mysql_result($result,0,"ccnum");

      } else {

      echo "No result! " . mysql_error();

      }

      ?>

      Греховность 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<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 – –

      Условие

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