Встроенные механизмы безопасности фреймворков Python

от автора

Введение

Проводя аудиты процессов разработки ПО, мы часто слышим, что функционал реализован во фреймворке, и это может вызывать вопросы со стороны специалистов по информационной безопасности. 

Python, будучи одним из популярных языков программирования, предлагает множество фреймворков, каждый из которых должен быть защищен и иметь встроенные механизмы безопасности либо возможности для встраивания этих механизмов. В этой статье попробуем разобраться, какие возможности действительно предоставляют фреймворки, рассмотрим механизмы безопасности и способы их настройки на примере распространенных фреймворков: Django, FastAPI и Flask.

Все эти фреймворки предоставляют разработчикам мощные инструменты для создания защищённых приложений, но их подходы и реализация отличаются.

1. Безопасность Django

Django — это мощный и надежный веб-фреймворк на Python, который включает в себя широкий спектр механизмов безопасности, способствующих созданию защищенных веб-приложений. Одна из ключевых особенностей Django по сравнению с другими фреймворками — это его встроенные механизмы безопасности, в которых представлен ряд инструментов для защиты от самых распространенных атак, таких как CSRF, XSS, SQL-инъекции и другие.

Встроенные механизмы безопасности

CSRF (Межсайтовая подделка запроса)

Django предотвращает атаки CSRF, используя токены, которые проверяются при каждом выполнении запроса на изменение данных. Токен CSRF гарантирует, что каждый запрос к серверу исходит от доверенного пользователя и с доверенного источника. Django автоматически добавляет токен CSRF в каждую форму и проверяет этот токен при получении POST-запроса.

XSS (Межсайтовый скриптинг)

Django защищает от XSS путем автоматического экранирования всех переменных, выводимых в шаблонах. Это предотвращает выполнение в браузере пользователя вредоносных скриптов, которые могли бы быть вставлены через формы ввода данных.

SQL-инъекции

Django использует ORM для генерации всех SQL-запросов к базе данных. Это изолирует разработчиков от непосредственного написания SQL-кода и защищает от SQL-инъекций, так как все запросы строятся с использованием параметризации и проверяются перед выполнением.

Обработка и хранение паролей

Django по умолчанию использует хеширование и соль для паролей, что делает процесс восстановления оригинального пароля из хеша крайне сложным. Для работы с паролями рекомендуется использовать встроенные классы Django, такие как User и make_password.

Аутентификация и авторизация

Django предлагает мощную систему аутентификации и авторизации, которая позволяет легко управлять пользователями, группами, правами доступа и более тонко настраивать доступ к ресурсам. Django предоставляет встроенные средства для аутентификации пользователей таких классов, как User и Authentication Middleware.

Clickjacking

Защита от clickjacking в Django осуществляется через механизм X-Frame-Options, который позволяет сайтам указывать на обстоятельства для загрузки контента во фрейме. Это предотвращает атаки, при которых злоумышленник может ввести пользователя в заблуждение, заставив его кликнуть на скрытый фрейм.

2. Настройка параметров безопасности Django

Настройка параметров безопасности в Django осуществляется через файл settings.py, который является центральным местом для конфигурации приложения. В этом файле можно настроить различные параметры, которые повлияют на безопасность вашего приложения.

Основные параметры безопасности

SECRET_KEY

  • Значение по умолчанию: Не задан по умолчанию, должен быть уникальным.

  • Назначение: Используется для криптографической подписи, важен для безопасности сессий и данных, связанных с cookies.

  • Примечание: Никогда не размещайте SECRET_KEY в публично доступных источниках.

DEBUG

  • Значение по умолчанию: True

  • Назначение: При включении выводит подробную информацию об ошибках, что может быть опасно на продакшн сервере.

  • Примечание: Всегда устанавливайте DEBUG = False на продакшн серверах.

ALLOWED_HOSTS

  • Значение по умолчанию: []

  • Назначение: Определяет список строк, представляющих имена хостов/доменов, которым разрешено обслуживать этот сайт.

  • Примечание: Настройте это значение в соответствии с доменами, на которых должно работать ваше приложение.

SECURE_BROWSER_XSS_FILTER

  • Значение по умолчанию: False

  • Назначение: Включает XSS фильтр в браузере пользователя.

  • Примечание: Рекомендуется устанавливать True для защиты от XSS атак.

X_FRAME_OPTIONS

  • Значение по умолчанию: DENY

  • Назначение: Управляет загрузкой сайта внутри тега <frame>, <iframe> , <object>.

  • Примечание: DENY блокирует все попытки загрузки страниц во фреймы, что помогает предотвратить clickjacking.

SECURE_SSL_REDIRECT

  • Значение по умолчанию: False

  • Назначение: Перенаправляет все HTTP запросы на HTTPS.

  • Примечание: Включите в продакшн, если ваш сайт работает полностью через HTTPS.

CSRF_COOKIE_SECURE

  • Значение по умолчанию: False

  • Назначение: Указывает, что cookie CSRF должен передаваться только по HTTPS.

  • Примечание: Включите, если ваш сайт использует HTTPS.

SESSION_COOKIE_SECURE

  • Значение по умолчанию: False

  • Назначение: Указывает, что cookie сессии должны передаваться только по HTTPS.

  • Примечание: Аналогично CSRF_COOKIE_SECURE, включите для HTTPS сайтов.

Пример настроенного файла конфигурации

# settings.py SECRET_KEY = 'your_secret_key_here' DEBUG = False ALLOWED_HOSTS = ['yourdomain.ru', 'www.yourdomain.ru']  SECURE_BROWSER_XSS_FILTER = True X_FRAME_OPTIONS = 'DENY' SECURE_SSL_REDIRECT = True  CSRF_COOKIE_SECURE = True SESSION_COOKIE_SECURE = True  # Дополнительные настройки безопасности SECURE_HSTS_SECONDS = 31536000  # Включение HSTS с длительностью один год SECURE_HSTS_INCLUDE_SUBDOMAINS = True SECURE_HSTS_PRELOAD = True

3. Безопасность FastAPI

FastAPI — это современный и высокопроизводительный фреймворк для создания API. Он не имеет встроенной системы безопасности в традиционном понимании.  Вместо этого он предоставляет модуль fastapi.security, который включает в себя ряд классов для аутентификации и работы с API ключами.

Встроенные механизмы безопасности

Аутентификация и авторизация

FastAPI поддерживает несколько способов аутентификации, включая:

  • OAuth2: С использованием OAuth2PasswordBearer, фреймворк может управлять токенами доступа, что часто применяется в современных API.

  • API ключи: Механизмы, такие как APIKeyHeader, APIKeyQuery и APIKeyCookie, позволяют использовать API ключи для простой аутентификации запросов.

Обработка и хранение паролей

FastAPI предлагает интеграцию с библиотеками, такими как passlib и bcrypt, для безопасного хеширования и проверки паролей. Эти библиотеки помогают разработчикам легко реализовать надежное хеширование паролей и их последующую проверку. FastAPI сам по себе не имеет встроенных инструментов для работы с паролями, но легко интегрируется с внешними библиотеками, предоставляющими такие возможности.

Защита от CSRF и XSS

  • CSRF: Поскольку FastAPI обычно используется для создания API с токенами аутентификации, CSRF не является такой значительной угрозой, как в традиционных веб-формах. Тем не менее, для сценариев, где используются cookie, рекомендуется применять сторонние решения для добавления токенов CSRF.

  • XSS: FastAPI автоматически не обрабатывает XSS, так как это относится к контенту, который генерируется на стороне клиента. Разработчики должны убедиться, что все пользовательские данные, выводимые в веб-приложениях, должным образом очищаются и экранируются.

Защита от SQL-инъекций

Использование ORM, таких как SQLAlchemy, предоставляет защиту от SQL-инъекций. FastAPI легко интегрируется с такими ORM, гарантируя, что все запросы к базе данных строго параметризованы — это предотвращает внедрение вредоносного кода.

Clickjacking

Для защиты от clickjacking разработчики могут использовать заголовки HTTP, такие как X-Frame-Options, для контроля загрузки страниц во фреймах. FastAPI позволяет легко добавлять заголовки через ответы API или средствами Starlette middleware.

4. Настройка параметров безопасности FastAPI

FastAPI сам по себе не имеет специализированного файла конфигурации безопасности. Вместо этого параметры безопасности и конфигурации определяются напрямую в коде приложения.

Основные механизмы безопасности

Аутентификация OAuth2:

  • Назначение: Используется класс OAuth2PasswordBearer для создания механизма получения токенов.

  • Примечание: Обеспечивает безопасность API путём проверки токенов доступа перед обработкой запросов пользователя.

  • Пример:

 from fastapi import Depends, FastAPI from fastapi.security import OAuth2PasswordBearer  app = FastAPI() oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/token")  @app.get("/users/me") async def read_users_me(token: str = Depends(oauth2_scheme)):     return {"token": token}

API ключи:

  • Назначение: Использование классов APIKeyHeader, APIKeyQuery, и APIKeyCookie для обработки API ключей.

  • Примечание: Проверка API ключей для доступа к определенным маршрутам или функциям API.

  • Пример:

 from fastapi import FastAPI, Security from fastapi.security.api_key import APIKeyHeader, APIKey  app = FastAPI() api_key_header = APIKeyHeader(name="X-API-Key")  async def get_api_key(api_key_header: str = Security(api_key_header)):     if api_key_header == "secret-key":         return "Authorized"     else:         return "Unauthorized"  @app.get("/secure-data") async def secure_data(authorization: str = Security(get_api_key)):     return {"status": authorization}

HTTP Basic Auth:

  • Назначение: Использование класса HTTPBasic для базовой аутентификации.

  • Примечание: Простая аутентификация пользователя с помощью имени пользователя и пароля.

  • Пример:

 import secrets from fastapi import FastAPI, Depends from fastapi.security import HTTPBasic, HTTPBasicCredentials from fastapi.exceptions import HTTPException  app = FastAPI() security = HTTPBasic()  def check_credentials(credentials: HTTPBasicCredentials = Depends(security)):     correct_username = secrets.compare_digest(credentials.username, "user")     correct_password = secrets.compare_digest(credentials.password, "password")     if not (correct_username and correct_password):         raise HTTPException(status_code=401, detail="Incorrect email or password")     return credentials  @app.get("/secure-area") def secure_area(credentials: HTTPBasicCredentials = Depends(check_credentials)):     return {"message": "Secure area accessed", "user": credentials.username}

Пример настроенного файла конфигурации

import secrets from fastapi import FastAPI, Depends, HTTPException from fastapi.security import OAuth2PasswordBearer, APIKeyHeader, HTTPBasic, HTTPBasicCredentials from jose import jwt  # Добавлен для обработки JWT токенов  app = FastAPI()  # Настройки безопасности security = HTTPBasic() oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/token") api_key_header = APIKeyHeader(name="X-API-Key")  # Функции проверки аутентификации def check_credentials(credentials: HTTPBasicCredentials = Depends(security)):     correct_username = secrets.compare_digest(credentials.username, "user")     correct_password = secrets.compare_digest(credentials.password, "password")     if not (correct_username and correct_password):         raise HTTPException(status_code=401, detail="Incorrect email or password")     return credentials  def get_api_key(api_key: str = Depends(api_key_header)):     if api_key == "correct_key":         return api_key     else:         raise HTTPException(status_code=401, detail="Invalid API key")  # Маршруты @app.post("/token") async def login():       # Предположим, что функция возвращает токен JWT после проверки учетных данных (опущено для простоты)     return {"access_token": "your_token"}  @app.get("/users/me") async def read_users_me(token: str = Depends(oauth2_scheme)):     # Возвращаем данные о пользователе,использующем токен     return {"token": token}  @app.get("/secure-area") def secure_area(credentials: HTTPBasicCredentials = Depends(check_credentials)):     # Доступ к защищенной области с использованием HTTP Basic Auth     return {"message": "Secure area accessed", "user": credentials.username}  @app.get("/secure-data") async def secure_data(api_key: str = Depends(get_api_key)):     # Доступ к защищенным данным с использованием API ключа     return {"message": "Access granted", "api_key": api_key}  if __name__ == "__main__":     import uvicorn     uvicorn.run(app, host="0.0.0.0", port=8000)

5. Безопасность Flask

Flask — это легковесный веб-фреймворк для Python, который широко используется для создания веб-приложений и API. Благодаря своей гибкости и минималистичной структуре Flask предоставляет разработчикам основу для реализации множества функций безопасности, но многие аспекты безопасности требуют ручной настройки или интеграции с внешними библиотеками.

Встроенные механизмы безопасности

Защита от CSRF (Межсайтовой подделки запроса)

Flask-WTF, расширение для Flask, обеспечивает защиту от CSRF. Это расширение автоматически добавляет токены CSRF к формам и проверяет эти токены при получении запросов, что помогает предотвратить несанкционированные действия от имени аутентифицированных пользователей.

Защита от XSS (Межсайтового скриптинга)

Для борьбы с XSS, Flask и его шаблонизатор Jinja2 автоматически экранируют все выводы переменных в шаблонах, если только не указано иное. Это предотвращает исполнение нежелательных скриптов, которые могли бы быть вставлены в содержимое страниц через пользовательский ввод.

Защита от SQL-инъекций

Использование ORM, таких как SQLAlchemy, предотвращает SQL-инъекции, так как запросы к базе данных формируются без прямой передачи параметров от пользователя, что исключает возможность выполнения вредоносного кода через входные данные.

Аутентификация и авторизация

Flask-Login — это инструмент для управления пользовательскими сессиями, который упрощает процесс аутентификации. Он помогает разработчикам контролировать доступ к определенным разделам приложения, требуя от пользователей входа в систему.

Защита от Clickjacking

Для защиты от кликджекинга можно использовать заголовок X-Frame-Options. Flask-Talisman, еще одно расширение, которое позволяет легко управлять заголовками безопасности, включая CSP (Content Security Policy) и помогает в борьбе с XSS и другими векторами атак.

6. Настройка параметров безопасности Flask

Во Flask параметры безопасности обычно задаются в файле конфигурации config.py. Flask не имеет встроенного файла конфигурации по умолчанию, но предлагает гибкую систему настройки.

Основные параметры безопасности

Ниже перечислены ключевые параметры безопасности, которые можно настроить в Flask:

SECRET_KEY

  • Значение по умолчанию: Не задан по умолчанию, должен быть уникальным.

  • Назначение: Используется для подписывания сессионных cookie и других безопасных операций.

  • Примечание: Ключ должен быть защищен и не раскрываться.

SESSION_COOKIE_SECURE

  • Значение по умолчанию: False

  • Назначение: Указывает браузеру использовать cookies только через HTTPS.

  • Примечание: Включайте, только если вы используете HTTPS.

SESSION_COOKIE_HTTPONLY

  • Значение по умолчанию: True

  • Назначение: Предотвращает доступ JavaScript к cookies.

  • Примечание: Помогает противостоять XSS атакам.

PERMANENT_SESSION_LIFETIME

  • Значение по умолчанию: 31 день

  • Назначение: Устанавливает продолжительность жизни постоянной сессии.

  • Примечание: Значение задается как объект timedelta.

REMEMBER_COOKIE_DURATION

  • Значение по умолчанию: 365 дней

  • Назначение: Устанавливает, как долго cookie будет сохранять информацию о входе в систему.

  • Примечание: При использовании Flask-Login.

Пример настроенного файла конфигурации

from datetime import timedelta from flask import Flask  app = Flask(__name__)  app.config['SECRET_KEY'] = 'your_secret_key_here' app.config['SESSION_COOKIE_SECURE'] = True app.config['SESSION_COOKIE_HTTPONLY'] = True app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(days=7) app.config['REMEMBER_COOKIE_DURATION'] = timedelta(days=14)  @app.route('/') def index():     return "Welcome to the Flask app!"  if __name__ == "__main__":     app.run(ssl_context='adhoc')

Заключение

Фреймворки Python предоставляют обширные возможности для обеспечения безопасности приложений. Независимо от того, используете ли вы Django, FastAPI или Flask, каждый из этих фреймворков обладает набором инструментов, способствующих защите от самых распространенных угроз встроенными или интегрируемыми способами. Однако важно понимать, что ни один инструмент или фреймворк не может обеспечить полную безопасность сам по себе. Применение лучших практик и использование проверенных библиотек играют ключевую роль в повышении безопасности ваших приложений. Резюмируя, можно сказать, что безопасность приложений зависит не только от выбранного фреймворка, но и от вашего внимания к деталям безопасности на каждом этапе разработки.

Автор: Артем Порфирьев, старший инженер по безопасности приложений УЦСБ


ссылка на оригинал статьи https://habr.com/ru/articles/851578/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *