П О Р Т А Л                            
С Е Т Е В Ы Х                          
П Р О Е К Т О В                        
  
Поиск по сайту:
                                                 
Главная

О проекте

Web-мастеру
     HTML & JavaScript
     SSI
     Perl
     PHP
     XML & XSLT
     Unix Shell

MySQL

Безопасность

Хостинг

Другое








Самое читаемое:

Учебник PHP - "Для Чайника".
Просмотров 3568 раз(а).

Иллюстрированный самоучитель по созданию сайтов.
Просмотров 6155 раз(а).

Учебник HTML.
Просмотров 3300 раз(а).

Руководство по PHP5.
Просмотров 5531 раз(а).

Хостинг через призму DNS.
Просмотров 4187 раз(а).

Подборка текстов стандартных документов.
Просмотров 55794 раз(а).

Учебник PHP - Самоучитель
Просмотров 3124 раз(а).

Документация на MySQL (учебник & справочное руководство)
Просмотров 6195 раз(а).

Внешние атаки...
Просмотров 3875 раз(а).

Учебник PHP.
Просмотров 2843 раз(а).

SSI в примерах.
Просмотров 37485 раз(а).






 
 
| Добавить в избранное | Сделать стартовой Project.Net.Ru | Помощь





Использование n-функций

По соглашению, функции стандартной библиотеки C определяют конец строки по нулевому байту. Например функция strcpy(3) копирует содержимое исходной строки в строку назначения пока не встретит нулевой байт. В некоторых случаях такое поведение становится опасным; мы видели, что следующий код содержит дыру в безопасности:
  #define LG_IDENT 128

  int fonction (const char * name)
  {
    char identity [LG_IDENT];
    strcpy (identity, name);
    ...
  }
Функции, ограничивающие длину копирования, обходят эту проблему. Эти функции имеют букву `n' в середине их названий, например, strncpy(3) как замена для strcpy(3), strncat(3) для strcat(3) или даже strnlen(3) для strlen(3).

Однако, вы должны быть осторожными с использованием ограничения функции strncpy(3), так как оно порождает краевой эффект: когда исходная строка меньше строки назначения, копия будет дополнена нулевыми символами до n-ой позиции, что делает приложение медленее. С другой стороны, если исходная строка длиннее, она будет урезана и копия поэтому не будет заканчиваться нулевым символом. Поэтому вы должны добавить его вручную. Принимая это во внимание, предыдущая подпрограмма приобретает вид:

  #define LG_IDENT 128

  int fonction (const char * name)
  {
    char identity [LG_IDENT+1];
    strncpy (identity, name, LG_IDENT);
    identity [LG_IDENT] = '\0';
    ...
  }
Естественно, те же принципы применимы и к процедурам работы с "широкими" символами (более 8 бит), например wcsncpy(3) нужно отдать предпочтение над wcscpy(3) или wcsncat(3) над wcscat(3). Конечно, программа становится больше, но также повышается и безопасность.

Как и strcpy(), strcat(3) не проверяет размер буфера. Функция strncat(3) добаляет символ в конец строки, если там еще есть место для этого. Замена strcat(buffer1, buffer2); на strncat(buffer1, buffer2, sizeof(buffer1)-1); исключает риск.

Функия sprintf() позволяет копировать форматированные данные в строку. У нее также есть версия, которая может проверять количество байт для копирования: snprintf(). Данная функция возвращает количество записанных символов в строку назначения (без учета '\0'). Проверка этого возвращаемого значения скажет вам, было ли произведено копирование должным образом:

  if (snprintf(dst, sizeof(dst) - 1, "%s", src) > sizeof(dst) - 1) {
    /* Переполнение */
    ...
  }

Очевидно, все это не стоит затраченного труда, если пользователь получает контроль над числом байт для копирования. Подобная дыра в BIND (Berkeley Internet Name Daemon) дала работу большому числу взломщиков:

  struct hosten *hp;
  unsigned long address;

  ...

  /* копирование адреса */
  memcpy(&address, hp->h_addr_list[0], hp->h_length);
  ...

Это всегда будет копировать 4 байта. И все-таки, если вы можете изменять hp->h_length, тогда вы можете изменять стек. Соответственно, обязательна проверка длины данных перед копированием:
  struct hosten *hp;
  unsigned long address;

  ...

  /* проверка */
  if (hp->h_length > sizeof(address))
    return 0;

  /* копирование адреса */
  memcpy(&address, hp->h_addr_list[0], hp->h_length);
  ...
В некоторых случаях, нельзя обрезать строку таким образом (путь, имя машины, URL, ...), обработка таких случаев должна производиться в программе раньше, как только введены данные.

Назад | Содержание | Вперед



Если Вы не нашли что искали, то рекомендую воспользоваться поиском по сайту:
 





Copyright © 2005-2016 Project.Net.Ru