аккуратно души питона, валидация данных

D2

Администратор
Регистрация
19 Фев 2025
Сообщения
4,380
Реакции
0
Автор p4p4
Источник https://xss.is

Не пишешь валидацию вводимых данных - ОШИБКА!
Реализуешь валидацию надеясь на синтаксический сахар - ФАТАЛЬНАЯ ОШИБКА!

Распространенным случаем эксплуатации уязвимости приложения при помощи инъекций является отсутствие валидации данных на стороне юзера.

Не редки случаи использования цикла while с инструкцией continue для валидации данных от пользователя
...

ПРИМЕР:
Python: Скопировать в буфер обмена
Код:
while True:
    age = input("Введите ваш возраст: ")
  
    # Проверка, является ли вводимые данные числом
    if not age.isdigit():
        print("ВОЗРАСТ ЭТО ЧИСЛО! Повторите пожалуйста.")
        continue  #  К началу цикла

    age = int(age)

    # Проверка на диапазон
    if age < 18 or age > 30:
        print("Не одобряем малолеток, отвергаем пенсов.")
        continue

    # Если ввод корректный, выходим из цикла
    break

В проверке подобных требований отсутствует возможность нанести дамаг, но это не значит, что данная реализация является эталоном при разработке

Использование continue в циклах для валидации данных может быть приемлемым, если оно не затрагивает компоненты программы, которые обрабатывают сенситив дату.

Сценарии, когда continue может быть безопасным:
- Валидация некритических данных
-Проверка формата ввода, спец. символы и т.п.
-Набросать примитивную валидацию в рамках тестирования в изолированной от внешнего мира среде​


ПРИМЕР НЕУДАЧНОГО ИСПОЛЬЗОВАНИЯ:
вырываю несколько строк из контекста полноценного проекта с БД

Python: Скопировать в буфер обмена
Код:
def user_data():
    while True:
        username = input("Ваше имя? ")
        # Проверка на пустое имя
        if not username:
            print("Имя не может быть пустым. ")
            continue  # Начало цикла

        # Проверка на пробелы
        if " " in username:
            print("Имя не может содержать пробелы. ")
            continue

        return username  # Возвращаем имя юзера при всех пройденных проверках

username = user_data()

print(f"Привет, {username}!")

👆
тУт дыра

Спойлер: О ДЫРЕ
Мейн проблема: инструкция continue переносит выполнение к началу цикла(новая итерация ), не обрабатывая потенциально опасные данные.
Если юзер введет admin; DROP TABLE users; в качестве имени пользователя, код выполнит следующее:

- Проверка на пустое имя
- Проверка на пробелы
- Перейдет к следующей итерации цикла, не обрабатывая DROP TABLE users;
- Возвратит "admin" как имя пользователя и проигнорирует оставшуюся часть строки​

КАК ИТОГ - та самая проигнорированная часть строки DROP TABLE users; может юзаться как вредоносный SQL-запрос, который удалит таблицу юзеров

ЕЩЕ МИНУСЫ(ситуативно):
Когда много условий проверки, continue может привести к запутанному, трудночитаемому коду.
Continue позволяет выйти только из текущей итерации цикла, при фулл выходе из цикла оптимальнее
break


Также стоит обратить внимание на комбинации условий проверки с логическими выражениями (and, or)

Оптимальная альтернатива для работы с чувствительными данными и сложной валидацией
👇
(библы):
validators, marshmallow
 
Сверху Снизу