Проект: Marketplace MVP (mp1)
Последнее обновление: 2025-11-08
.env.env в .gitignore - секреты не коммитятся# ✅ Хорошо - bcrypt/argon2
from passlib.context import CryptContext
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
hashed = pwd_context.hash("user_password") # Хешировать
is_valid = pwd_context.verify("user_password", hashed) # Проверить
# ❌ НИКОГДА:
# - Хранить пароли открытым текстом
# - Использовать MD5/SHA1 для паролей
# - Использовать обратимое шифрование для паролей
# ✅ Правильная настройка JWT
JWT_SECRET = os.getenv("JWT_SECRET") # Из .env
JWT_ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30 # Короткий TTL
# Payload не должен содержать чувствительных данных
payload = {
"user_id": user.id,
"exp": datetime.utcnow() + timedelta(minutes=30)
}
# ❌ НИКОГДА не включать в JWT:
# - Пароли
# - Секретные ключи
# - Персональные данные (паспорт, карты)
# ✅ Безопасные настройки сессий
SESSION_COOKIE_SECURE = True # Только HTTPS
SESSION_COOKIE_HTTPONLY = True # Недоступна для JS
SESSION_COOKIE_SAMESITE = 'Lax' # CSRF защита
SESSION_COOKIE_MAX_AGE = 3600 # 1 час
# Определение ролей
ROLES = {
"admin": ["read", "write", "delete", "manage_users"],
"editor": ["read", "write"],
"viewer": ["read"]
}
# Проверка прав
def require_permission(permission: str):
def decorator(func):
def wrapper(user, *args, **kwargs):
if permission not in ROLES.get(user.role, []):
raise PermissionError("Access denied")
return func(user, *args, **kwargs)
return wrapper
return decorator
@require_permission("write")
def update_order(user, order_id):
# Только users с правом "write"
pass
Что считается персональными данными:
- ФИО
- Email, телефон
- Адрес доставки
- IP адрес
- Cookies
Требования:
- [ ] Получать согласие на обработку
- [ ] Шифровать в БД (при необходимости)
- [ ] Право на удаление (GDPR Article 17)
- [ ] Право на экспорт данных
- [ ] Хранить не дольше необходимого
from cryptography.fernet import Fernet
# ✅ Шифрование номеров карт/паспортов
key = os.getenv("ENCRYPTION_KEY") # Из .env
fernet = Fernet(key)
# Зашифровать
encrypted = fernet.encrypt("4111111111111111".encode())
# Расшифровать
decrypted = fernet.decrypt(encrypted).decode()
# В БД хранить encrypted
# ✅ Защита от bruteforce
from slowapi import Limiter
from slowapi.util import get_remote_address
limiter = Limiter(key_func=get_remote_address)
@app.post("/login")
@limiter.limit("5/minute") # Макс 5 попыток в минуту
def login(credentials):
pass
# ✅ Строгие CORS правила
CORS_ORIGINS = [
"https://yourdomain.com",
"https://app.yourdomain.com"
]
# ❌ НИКОГДА:
CORS_ORIGINS = ["*"] # Разрешает всем!
# ✅ Проверка API ключа
def verify_api_key(api_key: str):
# НЕ хранить API ключи открытым текстом в БД!
# Хранить хеш (как пароли)
hashed = pwd_context.hash(api_key)
return db.query(APIKey).filter(
APIKey.key_hash == hashed,
APIKey.is_active == True
).first()
from pydantic import BaseModel, validator, EmailStr
class UserCreate(BaseModel):
email: EmailStr # Автоматическая валидация email
phone: str
@validator('phone')
def validate_phone(cls, v):
# Проверить формат телефона
if not re.match(r'^\+?\d{10,15}$', v):
raise ValueError('Invalid phone format')
return v
# ✅ Всегда валидировать на backend!
# Нельзя доверять frontend валидации
Регулярно проверять зависимости:
# Python
pip install safety
safety check
# Node.js
npm audit
npm audit fix
# Автоматически (GitHub Dependabot)
# Settings → Security → Dependabot alerts
| CVE ID | Компонент | Описание | Статус | Fix Version |
|---|---|---|---|---|
| {CVE_ID} | {КОМПОНЕНТ} | {ОПИСАНИЕ} | ✅ Fixed / ⚠️ Mitigated / 🔴 Open | {ВЕРСИЯ} |
Немедленно:
- Остановить утечку (отключить сервис/API)
- Собрать логи
- Оценить масштаб
В течение 1 часа:
- Уведомить ответственных
- Создать incident ticket
- Начать расследование
В течение 24 часов:
- Устранить уязвимость
- Уведомить пользователей (если затронуты их данные)
- Сменить все ключи/пароли
После инцидента:
- Post-mortem анализ
- Обновить процедуры
- Провести security audit
| Дата | Описание | Воздействие | Root Cause | Меры |
|---|---|---|---|---|
| 2025-11-08 | {ЧТО_ПРОИЗОШЛО} | {КТО_ПОСТРАДАЛ} | {ПРИЧИНА} | {ЧТО_СДЕЛАНО} |
Еженедельно:
- [ ] Проверить логи на подозрительную активность
- [ ] Обновить зависимости (security patches)
Ежемесячно:
- [ ] Ревью прав доступа пользователей
- [ ] Проверить актуальность SSL сертификатов
- [ ] Тест backup восстановления
Ежеквартально:
- [ ] Penetration testing
- [ ] Security code review
- [ ] Update security policies
Последнее обновление: 2025-11-08
Security Contact: {EMAIL}