• XSS.stack #1 – первый литературный журнал от юзеров форума

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

p4p4

(L1) cache
Пользователь
Регистрация
04.04.2024
Сообщения
504
Реакции
276
Автор p4p4
Источник https://xss.pro

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

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

Не редки случаи использования цикла 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
 
Последнее редактирование:
Перейдет к следующей итерации цикла, не обрабатывая DROP TABLE users;
- Возвратит "admin" как имя пользователя и проигнорирует оставшуюся часть строки​
КАК ИТОГ - та самая проигнорированная часть строки DROP TABLE users; может юзаться как вредоносный SQL-запрос, который удалит таблицу юзеров
Очень интересно, но совсем не понятно. По вашей логике должно вернуть "admin;" Но тут идёт проверка в условии на пробел в строке с инпута в переменной username. Оно разве пройдет проверку на истину при наличии пробела в строке? И как Вы используете оператор DROP в данном случае чтобы затереть таблицу? Прошу развернутого ответа.
 
Очень интересно, но совсем не понятно. По вашей логике должно вернуть "admin;" Но тут идёт проверка в условии на пробел в строке с инпута в переменной username. Оно разве пройдет проверку на истину при наличии пробела в строке? И как Вы используете оператор DROP в данном случае чтобы затереть таблицу? Прошу развернутого ответа.
не пон
 
не пон
Что непонятного? =) Тут и без интерпретатора понятно что Ваша функция (хотя-бы проверяйте что пишите) расходится с написанным:
Мейн проблема: инструкция continue переносит выполнение к началу цикла(новая итерация ), не обрабатывая потенциально опасные данные.
Если юзер введет admin; DROP TABLE users; в качестве имени пользователя, код выполнит следующее:

- Проверка на пустое имя
- Проверка на пробелы
- Перейдет к следующей итерации цикла, не обрабатывая DROP TABLE users;
- Возвратит "admin" как имя пользователя и проигнорирует оставшуюся часть строки​
КАК ИТОГ - та самая проигнорированная часть строки DROP TABLE users; может юзаться как вредоносный SQL-запрос, который удалит таблицу юзеров
Не пройдет это условие в истину если вбить эту строку admin; DROP TABLE users;, так как в этой строке есть пробелы.:
Python:
if " " in username:
    print("Имя не может содержать пробелы. ")
    continue
Но меня больше интересует этот момент:
КАК ИТОГ - та самая проигнорированная часть строки DROP TABLE users; может юзаться как вредоносный SQL-запрос, который удалит таблицу юзеров
Ладно, допустим я вбиваю строку без пробелов по Вашему примеру. Как вы используете оператор DROP на БД из переменной строкового типа "username"? Как использовать эту дыру? Раз уж сказали, пожалуйста аргументируйте.
 
Не пройдет это условие в истину если вбить эту строку admin; DROP TABLE users;, так как в этой строке есть пробелы.:
ааа, рил, я не обратил внимание, позже отредактирую как время будет
Как вы используете оператор DROP на БД из переменной USERNAME? Как использовать эту дыру? Раз уж сказали, пожалуйста аргументируйте.
думать надо, в гпт кину, переделаю, я сейчас на островах бузой соре
 
ааа, рил, я не обратил внимание, позже отредактирую как время будет

думать надо, в гпт кину, переделаю, я сейчас на островах бузой соре
Ну так вот за непроверенную информацию, и лишь бы сказануть того чего не знаете получайте заслуженный дизлайк (а ставить я их не люблю). Как ГПТ напишет что полезного и перестанет вводить участников форума в заблуждение, дизлайк сниму.
 
Ну так вот за непроверенную информацию, и лишь бы сказануть того чего не знаете получайте заслуженный дизлайк (а ставить я их не люблю). Как ГПТ напишет что полезного и перестанет вводить участников форума в заблуждение, дизлайк сниму.
оки доки
 
Автор p4p4
Источник https://xss.pro

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

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

Не редки случаи использования цикла 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
не пон
думать надо
в гпт кину, переделаю
1723042838065.png


играл сам с собой - проиграл
 
Пожалуйста, обратите внимание, что пользователь заблокирован
КАК ИТОГ - та самая проигнорированная часть строки DROP TABLE users; может юзаться как вредоносный SQL-запрос, который удалит таблицу юзеров
ну пример с sql injection очевидно неудачный.
На питоне мне доводилось мучать только sqlite. Там насколько я помню ты делаешь запрос вида "SELECT * FROM users WHERE username = ?" (или вместо вопроса %s, точно не вспомню) и передаешь username в списке вторым аргументом в функцию, где ты выполняешь запрос.
например так:
cursor.execute("SELECT admin FROM users WHERE username = %(username)s", {'username': username});
Собственно в username можно любое говно засунуть и оно отфильтруется. Есть конечно каста отдельных кретинов, которые создают запрос и конкатенируют к нему параметры, для них да фильтры нужны)))
Но самопальные фильтры будут хуже тех, что есть в либе.
 
ну пример с sql injection очевидно неудачный.
возможно да, скилла не хватает для удачных примеров

Собственно в username можно любое говно засунуть и оно отфильтруется.
точно не вспомню) и передаешь username в списке вторым аргументом в функцию, где ты выполняешь запрос.
где-то там, я хз, мне рил в падлу сорсы искать чо там ваще было, чтобы угодить кому-то...

чтобы дизлайк убрали АХАХАХ(умираю)
 
Автор p4p4
Источник https://xss.pro

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

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

Не редки случаи использования цикла 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
Немного не понятно при чём здесь SQL база данных и как это должно отразиться, так как ты не написал это в коде и не показал пример ( так как я +- хорошо знаю python я +- понял про что ты, но думаю новичкам будет не понятно ). Я думаю что любой кто делает программы с добавлением / созданием юзеров / паролей в базу данных продумывает такие моменты, тем более даже если есть подобные дыры на стадии тестов их довольно легко выявить, простой унит тест и готово. Я думаю что можно сразу заворачивать input в str что бы не создавать 100500 лишних строк, [ username = str(input('USERNAME: ') ], так же да бы исключить ввод комманд бд можно попробовать сплитовать пробелы ( ведь без них ты не сможешь ввести какую либо комманду ) как пример: [ try: username = username.split(' ') except: pass ], проверка на спец символы может быть реализована с помощью списка спец символов и цикла их поиска [ username.find() ] или перезаписи [ username.replace() ]. Если понравились мысли, можешь добавить к статье или написать 2ю часть.
 
новичкам
так я сам новичок )
продумывает такие моменты
поэтому когда сурсы с гита разбирал и сам писал, пришла мысль о том, что это немаловажный аспект и возможно кто-то будет задаваться вопросом о подобном
Если понравились мысли
понравились, себе сделал пометки;)
благодарю за здравую критику и конструктив!
 
так я сам новичок )

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

понравились, себе сделал пометки;)
благодарю за здравую критику и конструктив!
Не за что, тема на самом деле интересная, удачи :)
 
Распространенным случаем эксплуатации уязвимости приложения при помощи инъекций является отсутствие валидации данных на стороне юзера.
 
Такое может быть. Только не так как расписал автор (слышал звон, да не знает, где он), сразу видно в теме не разбирается.
Это правильный ответ:
Собственно в username можно любое говно засунуть и оно отфильтруется. Есть конечно каста отдельных кретинов, которые создают запрос и конкатенируют к нему параметры, для них да фильтры нужны)))
Если будет сделано как-то так:
Python:
def get_user(name):
    query = "SELECT * FROM users WHERE name = '" + name + "'"
    return execute_query(query)

Тогда да, в таком случае 'Admin'; DROP TABLE users;-- можно выполнить.

1724299098436.png


P.S. Выложил нормальную статью по безопасности написания кода на Python, взятую с хакера (в том числе с информацией по фильтрации ввода пользовательских данных):
https://xss.pro/threads/121212/
 
Последнее редактирование:


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх