1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/mirrors_Tencent-secguide

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
Python安全指南.md 21 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 30.11.2024 14:26 474be8d
  1. При использовании симметричного алгоритма шифрования необходимо защищать ключ шифрования. Когда алгоритм касается чувствительных или бизнес-данных, можно использовать асимметричный алгоритм для согласования ключа шифрования. Для защиты ключа можно использовать другие методы, такие как алгоритмы преобразования, для менее чувствительных данных.

2.3.2 Обязательное предотвращение жёсткого кодирования чувствительных конфигураций:

  • Запрещается жёсткое кодирование AK/SK, IP, учётных данных базы данных и другой подобной информации в исходном коде.
  • Следует использовать систему конфигурации или систему управления ключами KMS.

Класс бэкенда

I. Реализация кода

1.1 Проверка ввода

1.1.1 Обязательная проверка данных по типу:

  • Все внешние параметры программы должны быть проверены. Проверка включает, но не ограничивается следующими аспектами: длина данных, диапазон данных, тип данных и формат данных. Если проверка не пройдена, следует отказаться от данных.
  • Рекомендуется использовать следующие компоненты: Cerberus, jsonschema, Django-Validators.
# Пример использования 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 Операции SQL

1.2.1 Обязательное использование параметризованных запросов:

  • Используйте параметризованные запросы SQL, чтобы строго различать данные и команды и избегать уязвимостей SQL-инъекций.
# Неправильный пример
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()
  • Рекомендуется использовать ORM-фреймворк для работы с базой данных, например, SQLAlchemy.
# Установка 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 Обязательная фильтрация параметров:

  • При динамическом объединении внешних параметров с запросами SQL необходимо обеспечить их безопасное фильтрование.
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.3.1 Рекомендация избегать прямого вызова функций для выполнения системных команд:

  • В реализации связанных функций избегайте прямого вызова системных команд (таких как os.system(), os.popen(), subprocess.call() и т. д.), предпочитая использовать аналогичные операции для замены. Например, используйте API файловой системы для операций с файлами вместо прямого вызова команд операционной системы.
  • Если избежать этого невозможно, при выполнении команд избегайте объединения внешних данных и применяйте ограничения белого списка для выполняемых команд. 1.3.2 Обязательный фильтр символов, передаваемых функциям выполнения команд:
  • Когда функции, выполняющие системные команды, вызываются из программы, если передаваемая команда поступает извне, фильтруйте символы, которые могут использоваться для внедрения команд.
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 Обязательное запрещение небезопасного выполнения кода:

  • Не используйте функцию eval для обработки данных, поступающих извне.

1.4 Операции с файлами

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 Обязательное запрещение хранения внешних файлов в исполняемом каталоге:

  • Запретите хранение внешних файлов в каталоге WEB-контейнера, который может быть выполнен (appBase). Рекомендуется использовать библиотеку tempfile для обработки временных файлов и каталогов. 1.4. Пути

Необходимо избегать путей, пересекающих границы каталогов:

  • При сохранении файлов в локальной файловой системе необходимо проводить проверку пути на легальность и не допускать пересечения границ каталогов.
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. Разрешить только протоколы HTTP или HTTPS.
  2. Разобрать целевой URL и получить его хост.
  3. Разобрать хост и получить IP-адрес, на который он указывает, преобразовать его в long.
  4. Проверить, является ли IP-адрес внутренним IP-адресом.
  5. Отправить запрос на URL.
  6. Если есть перенаправление, выполнить шаг 1, иначе отправить запрос.

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 &lt;script&gt;evil()&lt;/script&gt; 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. Проверьте статус входа текущего пользователя.
  2. Получите проверенную информацию о текущем запросе пользователя из надёжной структуры (например, session). Запретите получение внешней информации о пользователях через параметры запросов или Cookie.
  3. Проверьте, имеет ли текущий пользователь разрешение на выполнение операции.
  4. Проверьте, есть ли у текущего пользователя доступ к обрабатываемым данным.
  5. Убедитесь, что операция выполняется ожидаемым пользователем.

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 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/mirrors_Tencent-secguide.git
git@api.gitlife.ru:oschina-mirror/mirrors_Tencent-secguide.git
oschina-mirror
mirrors_Tencent-secguide
mirrors_Tencent-secguide
main