2.3.2 Обязательное предотвращение жёсткого кодирования чувствительных конфигураций:
1.1.1 Обязательная проверка данных по типу:
# Пример использования Cerberus
v = Validator({'name': {'type': 'string'}})
v.validate({'name': 'john doe'})
# Пример использования jsonschema
schema = {
"type" : "object",
"properties" : {
"price" : {"type" : "number"},
"name" : {"type" : "string"},
},
}
validate(instance={"name" : "Eggs", "price" : 34.99}, schema=schema)
1.2.1 Обязательное использование параметризованных запросов:
# Неправильный пример
import mysql.connector
mydb = mysql.connector.connect(
... ...
)
cur = mydb.cursor()
userid = get_id_from_user()
# Использование % для непосредственного форматирования строки и объединения с SQL-запросом
cur.execute("SELECT `id`, `password` FROM `auth_user` WHERE `id`=%s " % (userid,))
myresult = cur.fetchall()
# Безопасный пример
import mysql.connector
mydb = mysql.connector.connect(
... ...
)
cur = mydb.cursor()
userid = get_id_from_user()
# Передача кортежа в качестве параметра
cur.execute("SELECT `id`, `password` FROM `auth_user` WHERE `id`=%s " , (userid,))
myresult = cur.fetchall()
# Установка sqlalchemy и инициализация соединения с базой данных
# pip install sqlalchemy
from sqlalchemy import create_engine
# Инициализация подключения к базе данных, изменение на ваше имя пользователя и пароль базы данных
engine = create_engine('mysql+mysqlconnector://user:password@host:port/DATABASE')
# Ссылка на типы данных
from sqlalchemy import Column, String, Integer, Float
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
# Определение объекта Player:
class Player(Base):
# Имя таблицы:
__tablename__ = 'player'
# Структура таблицы:
player_id = Column(Integer, primary_key=True, autoincrement=True)
team_id = Column(Integer)
player_name = Column(String(255))
height = Column(Float(3, 2))
# Вставка, удаление, обновление и запрос
from sqlalchemy.orm import sessionmaker
# Создание типа DBSession:
DBSession = sessionmaker(bind=engine)
# Создание объекта сеанса:
session = DBSession()
# Добавление:
new_player = Player(team_id=101, player_name="Tom", height=1.98)
session.add(new_player)
# Удаление:
row = session.query(Player).filter(Player.player_name=="Tom").first()
session.delete(row)
# Обновление:
row = session.query(Player).filter(Player.player_name=="Tom").first()
row.height = 1.99
# Запрос:
rows = session.query(Player).filter(Player.height >= 1.88).all()
# Сохранение изменений в базе данных:
session.commit()
# Закрытие сеанса:
session.close()
1.2.2 Обязательная фильтрация параметров:
def sql_filter(sql, max_length=20):
dirty_stuff = ["\"", "\\", "/", "*", "'", "=", "-", "#", ";", "<", ">", "+",
"&", "$", "(", ")", "%", "@", ","]
for stuff in dirty_stuff:
sql = sql.replace(stuff, "x")
return sql[:max_length]
1.3.1 Рекомендация избегать прямого вызова функций для выполнения системных команд:
import os
import sys
import shlex
domain = sys.argv[1]
# Замена символов, которые можно использовать для внедрения команд, на пробелы
badchars = "\n&;|'\"$()`-"
for char in badchars:
domain = domain.replace(char, " ")
result = os.system("nslookup " + shlex.quote(domain))
1.3.3 Обязательное запрещение небезопасного выполнения кода:
1.4.1 Обязательные ограничения типов файлов:
import os
ALLOWED_EXTENSIONS = ['txt','jpg','png']
def allowed_file(filename):
if ('.' in filename and
'..' not in filename and
os.path.splitext(filename)[1].lower() in ALLOWED_EXTENSIONS):
return filename
return None
1.4.2 Обязательное запрещение хранения внешних файлов в исполняемом каталоге:
Необходимо избегать путей, пересекающих границы каталогов:
import os
upload_dir = '/tmp/upload/' # ожидаемый каталог для загрузки
file_name = '../../etc/hosts' # имя файла, переданное пользователем
absolute_path = os.path.join(upload_dir, file_name) # /tmp/upload/../../etc/hosts
normalized_path = os.path.normpath(absolute_path) # /etc/hosts
if not normalized_path.startswith(upload_dir): # проверка, находится ли конечный путь в ожидаемом каталоге для загрузки
raise IOError()
1.4.4 Внешние сущности XML
Отключите методы работы с внешними сущностями XML для предотвращения атак XXE (XML External Entity).
from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
1.4.5 Небезопасные функции для десериализации YAML
Откажитесь от использования функции yaml.unsafe_load()
для десериализации данных YAML во избежание уязвимостей, связанных с десериализацией.
1.4.6 Избегайте конкатенации путей
Избегайте конкатенации внешних параметров при работе с путями к файлам. Рекомендуется сохранять пути к файлам как константы и проверять имена файлов (тип символов, длина).
1.4.7 Хеширование имён файлов
Рекомендуется заменять имена файлов случайными строками при сохранении файлов.
import uuid
def random_filename(filename):
ext = os.path.splitext(filename)[1]
new_filename = uuid.uuid4().hex + ext
return new_filename
1.5. Сетевые запросы
1.5.1 Ограничение доступа к сетевым ресурсам
При необходимости получения веб-контента, загрузки файлов или отображения изображений по указанному URL-адресу необходимо провести проверку безопасности URL-адреса:
1.6. Ответ сервера
1.6.1 Правильный тип пакета HTTP-ответа
Тип содержимого HTTP-пакета «Content-Type» должен быть правильно настроен в соответствии с типом ответа, и запрещено устанавливать тип «text/html» для ответов, отличных от HTML.
1.6.2 Безопасные заголовки HTTP-ответов
X-Content-Type-Options: добавьте заголовок ответа «X-Content-Type-Options» и установите значение «nosniff».
HttpOnly: контролируйте файлы cookie аутентификации пользователя и устанавливайте атрибут HttpOnly, чтобы предотвратить их использование XSS-уязвимостями и манипуляциями JavaScript.
X-Frame-Options: установите заголовок ответа X-Frame-Options и настройте его в зависимости от требований. Этот заголовок используется для указания того, что текущая страница не должна отображаться во фреймах, таких как frame, iframe и embed. Это помогает избежать проблем с кликджекингом. Он имеет три возможных значения: DENY — текущая страница не может быть загружена ни в один фрейм; SAMEORIGIN — фреймы могут быть загружены только из того же источника; ALLOW-FROM origin — определяет источники, которым разрешено загружать фреймы.
1.6.3 Кодирование вывода страниц
Если тип содержимого ответа — «text/html», необходимо обработать ответ с помощью кодирования.
# Рекомендуется использовать библиотеку bleach, поддерживаемую Mozilla, для фильтрации
import bleach
bleach.clean('an <script>evil()</script> example')
# u'an <script>evil()</script> example'
1.7. Данные
1.7.1 Считывание и хранение чувствительных данных
Используйте алгоритмы SHA2 и RSA для шифрования чувствительных данных перед сохранением. Храните чувствительные данные в отдельном слое хранения и включайте контроль доступа на уровне доступа. Немедленно удаляйте временные файлы и кэш, когда они больше не нужны.
1.7.2 Деанонимизация чувствительных данных на сервере
Чувствительные данные должны быть анонимизированы на сервере перед возвратом, а не на стороне клиента.
1.7.3 Хранение и отображение чувствительных данных
Не отображайте и не храните следующие данные:
— пароли; — ответы на вопросы безопасности; — личную информацию, такую как идентификационные номера и медицинские данные.
За исключением финансовых услуг, не храните номера кредитных карт и логины.
1.7.4 Отображение личных данных
В случае необходимости отображения личных данных выполните их анонимизацию. Например, отобразите первые и последние цифры номера удостоверения личности (например, 3***1), спрячьте шесть средних цифр номера мобильного телефона (например, 13448) и так далее.
1.7.5 Скрытые адреса серверов
Если приложение предоставляет доступ к административным страницам, используйте случайные строки для скрытия адресов серверов.
# Не рекомендуется использовать такой подход
admin_login_url = "xxxx/login"
# Пример безопасного подхода
admin_login_url = "xxxx/ranD0Str"
1.8. Управление правами доступа
1.8.1 Аутентификация по умолчанию
По умолчанию система должна требовать аутентификацию (используя белый список для открытых интерфейсов или страниц).
1.8.2 Принцип наименьших привилегий
Пользователи по умолчанию не должны иметь никаких прав доступа.
1.8.3 Предотвращение несанкционированного доступа
Для операций, которые не являются общедоступными, необходимо проверить текущий статус входа пользователя, получить информацию о пользователе из доверенной структуры, запретить получение внешней информации о пользователе через параметры запроса или Cookie и проверить, имеет ли текущий пользователь право выполнять операцию и имеет ли он доступ к данным, с которыми работает.
1.8.4 Своевременное удаление ненужных прав
Приложение должно регулярно удалять ненужные права пользователей.
1.9. Обработка исключений
1.9.1 Не выводить ошибки на клиентскую сторону
Следует использовать конструкции try/except/finally для обработки системных исключений и избегать вывода сообщений об ошибках на клиентскую сторону. В среде разработки не следует включать режим отладки или выводить журналы работы приложения на клиентскую сторону.
1.9.2 Запрет на вывод чувствительных данных в сообщениях об исключениях
1.10. Безопасность Flask
1.10.1 Отключить режим отладки в рабочей среде
1.10.2 Следовать рекомендациям по безопасности Flask
Следуйте рекомендациям по обеспечению безопасности, представленным в документации Flask.
https://flask.palletsprojects.com/en/latest/security/
1.11. Безопасность Django
1.11.1 Отключение режима отладки в рабочей среде
1.11.2 Использование встроенных функций безопасности Django
Сохраните встроенные функции безопасности Django и избегайте их отключения.
Django предоставляет встроенные функции безопасности, такие как защита от XSS, CSRF, SQL-инъекций и кликджекинга. Рекомендуется не отключать эти функции без необходимости.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )