Безопасное кодирование
![]() | В этой статье есть несколько проблем. Пожалуйста, помогите улучшить его или обсудите эти проблемы на странице обсуждения . ( Узнайте, как и когда удалять эти шаблонные сообщения )
|
Безопасное кодирование — это практика разработки компьютерного программного обеспечения таким образом, чтобы предотвратить случайное появление уязвимостей безопасности . Дефекты, ошибки и логические ошибки неизменно являются основной причиной часто используемых уязвимостей программного обеспечения. [1] Проанализировав тысячи зарегистрированных уязвимостей, специалисты по безопасности обнаружили, что большинство уязвимостей возникают из-за относительно небольшого количества распространенных ошибок программирования. Выявляя небезопасные методы кодирования, которые приводят к этим ошибкам, и обучая разработчиков безопасным альтернативам, организации могут предпринять активные шаги, чтобы помочь значительно уменьшить или устранить уязвимости в программном обеспечении перед его развертыванием. [2]
Некоторые ученые полагают, что для эффективного противодействия угрозам, связанным с кибербезопасностью , необходимая безопасность должна быть запрограммирована или «встроена» в системы. Поскольку безопасность встроена в программное обеспечение, это гарантирует защиту от внутренних атак и снижает угрозу безопасности приложений. [3]
Предотвращение переполнения буфера [ править ]
Переполнение буфера — распространенная уязвимость безопасности программного обеспечения — возникает, когда процесс пытается сохранить данные за пределами буфера фиксированной длины. Например, если имеется 8 слотов для хранения предметов, возникнет проблема при попытке сохранить 9 предметов. В памяти компьютера переполненные данные могут перезаписать данные в следующем месте, что может привести к уязвимости безопасности (разрушению стека) или завершению программы (ошибке сегментации). [1]
Пример программы C, склонной к переполнению буфера:
int vulnerable_function(char * large_user_input) {
char dst[SMALL];
strcpy(dst, large_user_input);
}
Если пользовательский ввод превышает буфер назначения, произойдет переполнение буфера. Чтобы исправить эту небезопасную программу, используйте strncpy, чтобы предотвратить возможное переполнение буфера.
int secure_function(char * user_input) {
char dst[BUF_SIZE];
// copy a maximum of BUF_SIZE bytes
strncpy(dst, user_input, BUF_SIZE);
// set the last character in the buffer to NUL.
dst[BUF_SIZE -1] = '\0';
}
Другая безопасная альтернатива — динамическое выделение памяти в куче с помощью malloc .
char * secure_copy(char * src) {
size_t len = strlen(src);
char * dst = (char *) malloc(len + 1);
if (dst != NULL) {
strncpy(dst, src, len);
// append null terminator
dst[len] = '\0';
}
return dst;
}
В приведенном выше фрагменте кода программа пытается скопировать содержимое src в dst , а также проверяет возвращаемое значение malloc, чтобы убедиться, что для буфера назначения можно выделить достаточно памяти.
Предотвращение атак с использованием форматной строки [ править ]
Атака форматной строки — это когда злонамеренный пользователь предоставляет определенные входные данные, которые в конечном итоге будут введены в качестве аргумента функции, выполняющей форматирование, например printf() . Атака включает в себя чтение или запись данных в стек .
Функция C printf записывает вывод в стандартный вывод. Если параметр функции printf отформатирован неправильно, может возникнуть несколько ошибок безопасности. Ниже представлена программа, уязвимая для атаки на форматную строку.
int vulnerable_print(char * malicious_input) {
printf(malicious_input);
}
Вредоносный аргумент, переданный программе, может иметь вид «%s%s%s%s%s%s%s», что может привести к сбою программы из-за неправильного чтения памяти.
Предотвращение целочисленного переполнения [ править ]
Переполнение целого числа происходит, когда в результате арифметической операции получается целое число, слишком большое для представления в доступном пространстве. Программа, которая не проверяет должным образом целочисленное переполнение, создает потенциальные программные ошибки и эксплойты.
Ниже приведена функция на C++ , которая пытается подтвердить, что сумма x и y меньше или равна определенному значению MAX:
bool sumIsValid_flawed(unsigned int x, unsigned int y) {
unsigned int sum = x + y;
return sum <= MAX;
}
Проблема с кодом в том, что он не проверяет переполнение целых чисел при операции сложения. Если сумма x и y больше максимально возможного значения unsigned int
, операция сложения приведет к переполнению и, возможно, приведет к значению, меньшему или равному MAX, даже если сумма x и y больше MAX.
Ниже приведена функция, которая проверяет переполнение, подтверждая, что сумма больше или равна как x, так и y. Если бы сумма действительно переполнилась, она была бы меньше x или меньше y.
bool sumIsValid_secure(unsigned int x, unsigned int y) {
unsigned int sum = x + y;
return sum >= x && sum >= y && sum <= MAX;
}
Предотвращение обхода пути [ править ]
Обход пути — это уязвимость, при которой пути, предоставленные из ненадежного источника, интерпретируются таким образом, что возможен несанкционированный доступ к файлу.
Например, рассмотрим сценарий, который извлекает статью, беря имя файла, которое затем читается сценарием и анализируется . Такой сценарий может использовать следующий гипотетический URL-адрес для получения статьи о корме для собак :
https://www.example.net/cgi-bin/article.sh?name=dogfood.html
Если в сценарии не предусмотрена проверка входных данных, а вместо этого он полагается на то, что имя файла всегда допустимо, злоумышленник может подделать URL-адрес для получения файлов конфигурации с веб-сервера:
https://www.example.net/cgi-bin/article.sh?name=../../../../../etc/passwd
В зависимости от сценария это может открыть файл /etc/passwd , который в Unix-подобных системах содержит (среди прочего) идентификаторы пользователей , их имена для входа , пути к домашнему каталогу и оболочки . ( см. в разделе SQL-инъекция Подобную атаку .)
См. также [ править ]
Примечания [ править ]
- ^ Jump up to: Перейти обратно: а б Вьега, Джон; Гэри МакГроу (2001). Создание безопасного программного обеспечения: как правильно избежать проблем с безопасностью . Мэддисон-Уэсли Профессионал. п. 528. ИСБН 978-0201721522 .
- ^ Тейлор, Блэр; Азадеган, Шива (22 сентября 2006 г.). «Внедрение принципов безопасного кодирования и анализа рисков в учебную программу бакалавриата по информатике и информационным системам» . Материалы 3-й ежегодной конференции по разработке учебных программ по информационной безопасности . InfoSecCD '06. Кеннесо, Джорджия: Ассоциация вычислительной техники. стр. 24–29. дои : 10.1145/1231047.1231053 . ISBN 978-1-59593-437-6 . S2CID 2452783 .
- ^ Рассел Л., Джонс (декабрь 2004 г.). «Безопасное кодирование: встраивание безопасности в жизненный цикл разработки программного обеспечения» . Безопасность информационных систем . ПроКвест 229507883 .
Ссылки [ править ]
- Тейлор, Арт; Брайан Бьюдж; Рэнди Лэйман (2006). Взлом открытых J2EE и Java . МакГроу-Хилл Примис. п. 426. ИСБН 0-390-59975-1 .