[English](/docs/security) | **Русский**

# Правила безопасности

<!-- doc-map: reader=user; zone=security -->

См. также: [security-checklist.md](https://github.com/Kibertum/tausik-core/blob/v1.11.0/docs/en/security-checklist.md) — OWASP Top 10 чек-лист.

## Основные принципы

1. **Никогда не доверяй пользовательскому вводу** — валидируй всё
2. **Минимальные привилегии** — давай только необходимое
3. **Эшелонированная защита** — множество слоёв защиты
4. **Безопасный отказ** — ошибки не должны раскрывать информацию
5. **Аудит всего** — логируй события безопасности

---

## OWASP Top 10 (кратко)

### A01: Нарушение контроля доступа
- Проверяй авторизацию на КАЖДОМ endpoint
- Не доверяй client-side данным
- Проверяй ownership ресурсов

### A02: Криптографические сбои
- Используй argon2/bcrypt для паролей (НЕ MD5/SHA1)
- Secrets через переменные окружения
- HTTPS обязателен в production

### A03: Инъекции
- Параметризованные SQL запросы
- textContent вместо innerHTML
- Экранируй вывод для XSS prevention

### A05: Неправильная конфигурация
- Безопасные сообщения об ошибках
- Настроенные security headers
- Специфичный CORS (не *)

### A07: Сбои аутентификации
- Rate limiting на auth endpoints
- Secure cookie flags (httpOnly, secure, sameSite)
- Сильные требования к паролям

---

## Валидация входов

### Обязательные проверки
- Тип данных
- Длина/размер
- Формат (email, URL, etc)
- Допустимые значения (whitelist)

### Где валидировать
- На границе системы (API endpoints)
- Перед сохранением в БД
- Перед отображением пользователю

---

## Аутентификация

### Требования к паролям
- Минимум 12 символов
- Смесь uppercase, lowercase, цифр, символов
- Проверка против списков популярных паролей

### Cookie безопасность
```
httpOnly: true    — нет доступа из JS
secure: true      — только HTTPS
sameSite: strict  — защита от CSRF
```

---

## Управление секретами

### Категорически нельзя
- Хардкодить секреты в коде
- Коммитить .env файлы
- Логировать секреты

### Правильно
- Переменные окружения
- Secrets managers (Vault, AWS Secrets Manager)
- Регулярная ротация credentials

### .gitignore для секретов
```
.env
.env.*
!.env.example
secrets/
*.pem
*.key
```

---

## Логирование для безопасности

### Что логировать
- Успешные/неуспешные логины
- Изменения прав доступа
- Доступ к sensitive данным
- Административные действия

### Что НЕ логировать
- Пароли (даже хэшированные)
- API ключи
- Session токены
- Номера карт
- PII в открытом виде

---

## Чеклисты

### Перед каждым коммитом
- [ ] Нет хардкодированных секретов
- [ ] Валидация входов на всех endpoints
- [ ] Проверки авторизации присутствуют
- [ ] Сообщения об ошибках не раскрывают информацию
- [ ] Нет SQL/command injection
- [ ] Rate limiting на sensitive endpoints

### Перед каждым деплоем
- [ ] Dependencies проверены на уязвимости
- [ ] Security headers настроены
- [ ] HTTPS enforced
- [ ] Секреты в безопасном хранилище
- [ ] Логирование настроено правильно

---

## Гарантии TAUSIK

- `bash_firewall.py` блокирует `rm -rf /`, `Remove-Item -Recurse -Force C:\`, `git reset --hard origin`, force-push — **на обоих оболочечных каналах**, Bash и PowerShell. Полная матрица покрытия каналов: [`enforcement-coverage.md`](/ru/docs/enforcement-coverage)
- `git_push_gate.py` требует `TAUSIK_ALLOW_PUSH=1` (выставляется `/ship` после подтверждения)
- `memory_pretool_block.py` блокирует Write/Edit/MultiEdit **и Bash/PowerShell** в любой чужой memory-сток — `~/.claude/**/memory/`, `.cursor/rules/`, `.windsurf/rules/`, `.github/copilot-instructions.md`, `.clinerules`, `.roo/rules/`, `.continue/rules/`, `.aider*` (deny-list: `scripts/memory_sinks.py`)
- Гейт `memory_route` и хук `pre-commit` применяют тот же deny-list IDE-агностично по working tree; литмус-блок в генерируемых rule-файлах закрывает хосты с облачной памятью, которая не пишет файла вообще
- `publication_boundary.py` (на детекторах `brain_scrubbing`) вычищает пути, e-mail, приватные URL и имена проектов в `knowledge export --redacted`
- Валидация slug'ов в scaffold ролей/стеков блокирует path traversal
- Команду дефолтного гейта нельзя подменить чужим инструментом: `.tausik/config.json` едет вместе с репозиторием, поэтому переопределение `gates.<имя>.command` обязано вызывать тот же инструмент, что и дефолт. Аргументы, путь и обёртку-раннер менять можно (`vendor/bin/phpstan analyse --level=8` принимается; `eslint {files}` вместо дефолтного `npx eslint {files}` тоже — обёртки видны насквозь), сам инструмент — нет (`python -c pass` вместо `ruff` отвергается, гейт остаётся с дефолтной командой)
- Установка скиллов гейтится на **обоих** путях в активированное дерево — `install` (`skill_manager.copy_skill`) и `activate` (`service_skills.skill_activate`): подпись издателя (ed25519, key-pinned на репо), guard'ы обхода пути и симлинков и общий **контент-скан невидимого Unicode** (`skill_content_scan.assert_skill_tree_clean`), который отказывает скиллу, прячущему инструкции для агента в zero-width / bidi / U+E0000 tag-block символах, по каждому prose/config/script-файлу. Полная модель: [`skill-supply-chain-threat-model.md`](https://github.com/Kibertum/tausik-core/blob/v1.11.0/docs/ru/skill-supply-chain-threat-model.md)

### Границы гарантий

Надзор проверяется машиной там, где это возможно машине. Оставшееся записано здесь честно, а не подразумевается.

- **Инертные аргументы того же инструмента НЕ обнаруживаются.** Проверка сравнивает вызываемый инструмент, а не смысл вызова, поэтому `ruff --version` или `pytest --collect-only` в переопределении пройдут: инструмент тот самый, гейт формально включён и всегда зелёный. Машинного критерия «команда делает настоящую работу» не существует, а правило «команда обязана начинаться с дефолтного префикса» сломало бы и вендоренный путь, и легитимный отказ от обёртки `npx`. Переопределения команд гейтов в чужом репозитории читай глазами — гейт с подозрительно быстрым зелёным заслуживает взгляда на свою команду.
- **Встроенные гейты** (`filesize`, `class_surface`, `tdd_order`, `renar_drift_*`) команды не имеют вовсе; попытка её добавить отвергается.
