Безопасное кодирование - Secure coding

Безопасное кодирование - это практика разработки компьютерного программного обеспечения таким образом, чтобы не допустить случайного появления уязвимостей в системе безопасности . Дефекты, ошибки и логические ошибки неизменно являются основной причиной часто используемых уязвимостей программного обеспечения. Проанализировав тысячи обнаруженных уязвимостей, специалисты по безопасности обнаружили, что большинство уязвимостей возникает из-за относительно небольшого количества распространенных ошибок программирования программного обеспечения. Выявляя небезопасные методы кодирования, которые приводят к этим ошибкам, и обучая разработчиков безопасным альтернативам, организации могут предпринять упреждающие шаги, чтобы помочь значительно уменьшить или устранить уязвимости в программном обеспечении перед развертыванием.

Предотвращение переполнения буфера

Переполнение буфера , распространенная уязвимость системы безопасности программного обеспечения, происходит, когда процесс пытается сохранить данные за пределами буфера фиксированной длины. Например, если имеется 8 ячеек для хранения предметов, возникнет проблема, если будет предпринята попытка сохранить 9 предметов. В памяти компьютера переполненные данные могут перезаписать данные в следующем месте, что может привести к уязвимости системы безопасности (разбиение стека) или завершению программы (ошибка сегментации).

Пример программы 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);
}

Другая безопасная альтернатива - динамически выделять память в куче с помощью 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, чтобы убедиться, что для целевого буфера можно выделить достаточно памяти.

Предотвращение атак с форматной строкой

Формат атака Строки , когда злоумышленник поставляет конкретные материалы , которые в конечном итоге будут введены в качестве аргумента в функцию , которая выполняет форматирование, такие как Е () . Атака включает в себя чтение злоумышленником или запись в стек .

Функция C printf записывает вывод в stdout. Если параметр функции 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 больше максимально возможного значения an 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-инъекцию для подобной атаки.)

Смотрите также

Примечания

использованная литература

  • Тейлор, Искусство; Брайан Бюдж; Рэнди Лэйман (2006). Взлом открытых J2EE и Java . McGraw-Hill Primis. п. 426. ISBN. 0-390-59975-1.

внешние ссылки