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

О проекте

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

MySQL

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

Хостинг

Другое








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

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

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

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

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

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

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

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

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

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

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

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






 
 
| Добавить в избранное | Сделать стартовой 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