Files
DLE/docs.ru/security.md

1312 lines
54 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[English](../docs.en/security.md) | **Русский**
# Безопасность Digital Legal Entity (DLE)
## Содержание
1. [Введение](#введение)
2. [Модель безопасности](#модель-безопасности)
3. [Контроль доступа на основе токенов](#контроль-доступа-на-основе-токенов)
4. [Безопасность смарт-контрактов](#безопасность-смарт-контрактов)
5. [Защита от взлома кошельков](#защита-от-взлома-кошельков)
6. [Безопасность веб-приложения](#безопасность-веб-приложения)
7. [Управление модулями](#управление-модулями)
8. [Аудит и мониторинг](#аудит-и-мониторинг)
9. [Рекомендации по безопасности](#рекомендации-по-безопасности)
10. [Сценарии атак и защита](#сценарии-атак-и-защита)
---
## Введение
Digital Legal Entity (DLE) построен с фокусом на **безопасность на всех уровнях**:
- Контроль доступа через блокчейн-токены
- Защита смарт-контрактов от взлома
- Невозможность кражи токенов даже при взломе кошелька
- Управление только через голосование с кворумом
### Ключевые принципы безопасности
1. **Защита по умолчанию** - все действия запрещены, пока явно не разрешены
2. **Минимальные привилегии** - каждый получает только необходимые права
3. **Прозрачность** - все действия записаны на блокчейне
4. **Неизменяемость** - невозможно подделать историю
5. **Коллективный контроль** - критичные операции только через голосование
---
## Модель безопасности
### Архитектура безопасности
```
┌─────────────────────────────────────────────────────────────┐
│ Уровни защиты DLE │
├─────────────────────────────────────────────────────────────┤
│ │
│ Уровень 1: Блокчейн (Неизменяемая база) │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ • Смарт-контракт DLE (проверен, иммутабельный) │ │
│ │ • Токены управления (ERC20Votes) │ │
│ │ • История всех операций на блокчейне │ │
│ │ • Невозможность изменения правил без голосования │ │
│ └───────────────────────────────────────────────────────┘ │
│ ↑ │
│ Уровень 2: Веб-приложение (Backend) │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ • Проверка токенов в реальном времени │ │
│ │ • Аутентификация через кошелек (SIWE) │ │
│ │ • Шифрование данных (AES-256) │ │
│ │ • Rate limiting и защита от DDoS │ │
│ └───────────────────────────────────────────────────────┘ │
│ ↑ │
│ Уровень 3: Frontend (Vue.js) │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ • Подключение к кошельку │ │
│ │ • Подпись транзакций │ │
│ │ • XSS защита (DOMPurify) │ │
│ │ • CSRF токены │ │
│ └───────────────────────────────────────────────────────┘ │
│ ↑ │
│ Уровень 4: Пользователь │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ • Приватный ключ кошелька (MetaMask, WalletConnect) │ │
│ │ • Подтверждение каждой операции │ │
│ └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
### Модель угроз
| Угроза | Уровень риска | Защита |
|--------|---------------|--------|
| **Взлом кошелька** | Средний | Токены нельзя перевести без голосования |
| **Взлом веб-приложения** | Низкий | Все права проверяются на блокчейне, управление через блокчейн-сканеры |
| **Компрометация смарт-контракта** | Низкий | Аудит, OpenZeppelin, иммутабельность |
| **DDoS атака** | Средний | Rate limiting, CDN, резервные сервера |
| **Фишинг** | Высокий | Обучение пользователей, проверка домена |
| **Insider threat** | Низкий | Все действия через голосование |
### Критически важно: веб-приложение — это только интерфейс
**Ключевая особенность архитектуры DLE:**
```
┌─────────────────────────────────────────────────────────┐
Веб-приложение (интерфейс) │
│ │
│ Frontend + Backend = УДОБСТВО использования │
│ • Красивый UI │
│ • Удобная навигация │
│ • Быстрый доступ к функциям │
│ │
│ Может быть взломано/недоступно │
│ ✅ НО! Активы бизнеса защищены │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ Блокчейн (реальная власть) │
│ │
│ Смарт-контракты = РЕАЛЬНОЕ управление активами │
│ • Токены управления │
│ • Казна с активами │
│ • Правила голосования │
│ • История всех решений │
│ │
│ Защищено криптографией │
│ ✅ Работает независимо от веб-приложения │
└─────────────────────────────────────────────────────────┘
```
**Что происходит при взломе веб-приложения:**
```
Веб-приложение взломано/недоступно:
├── ❌ Веб-интерфейс не работает
├── ❌ Backend может показывать неверную информацию
├── ❌ Frontend может быть подменен
НО:
├── ✅ Все активы бизнеса остаются на блокчейне
├── ✅ Смарт-контракты продолжают работать
├── ✅ Токены невозможно украсть
├── ✅ Можно управлять через Etherscan/Polygonscan/др.
└── ✅ Можно создать новый frontend и подключить к тем же контрактам
```
**Реальный пример:**
1. Злоумышленник взламывает ваш сервер с веб-приложением
2. Пытается показать поддельные балансы токенов
3. **Но**: Реальные балансы на блокчейне остаются неизменными
4. Вы открываете Etherscan и видите правду
5. Создаете предложение через Etherscan на восстановление
6. Голосуете и исполняете предложение
7. Восстанавливаете веб-приложение
8. **Результат**: Ни один токен не потерян ✅
---
## Контроль доступа на основе токенов
### Принцип работы
**Без токенов доступ к приложению НЕВОЗМОЖЕН.**
```
Попытка доступа к DLE:
├── 1. Пользователь подключает кошелек
├── 2. Backend проверяет баланс токенов в смарт-контракте
├── 3. Если токенов НЕТ → Доступ ЗАПРЕЩЕН
└── 4. Если токены ЕСТЬ → Доступ разрешен (уровень зависит от количества)
```
### Уровни доступа
| Токенов на балансе | Уровень доступа | Права |
|-------------------|-----------------|-------|
| **0 токенов** | ❌ Нет доступа | Только страница "Нет доступа" |
| **1+ токенов** | ✅ ReadOnly | Просмотр данных |
| **100+ токенов** | ✅ Editor | Редактирование, создание |
| **Любое количество** | 🗳️ Голосование | 1 токен = 1 голос |
### Проверка токенов в реальном времени
**Backend** постоянно проверяет баланс токенов:
```javascript
// Каждый запрос проверяет токены
async function checkAccess(req, res, next) {
const address = req.session.address;
// Получаем баланс токенов из смарт-контракта
const dleContract = new ethers.Contract(dleAddress, dleAbi, provider);
const balance = await dleContract.balanceOf(address);
if (balance === 0n) {
return res.status(403).json({
error: 'Доступ запрещен: нет токенов'
});
}
// Определяем уровень доступа
const accessLevel = determineAccessLevel(balance);
req.user = { address, balance, accessLevel };
next();
}
```
**Важно**: Проверка происходит на **каждом запросе**, поэтому:
- ✅ Если токены переведены → доступ мгновенно теряется
- ✅ Если токены получены → доступ мгновенно появляется
- ✅ Невозможно обойти проверку
### Начальное распределение токенов
**Токены распределяет владелец при деплое смарт-контракта:**
```solidity
constructor(DLEConfig memory config) {
// Создаем токены
_mint(address(this), totalSupply);
// Распределяем среди партнеров
for (uint i = 0; i < config.initialPartners.length; i++) {
_transfer(
address(this),
config.initialPartners[i],
config.initialAmounts[i]
);
}
}
```
**Процесс**:
1. Владелец кошелька деплоит смарт-контракт DLE
2. Указывает адреса партнеров и количество токенов для каждого
3. Токены автоматически распределяются при деплое
4. После этого все изменения только через голосование
**Пример распределения**:
```javascript
const config = {
initialPartners: [
'0xAlice...', // Основатель 1
'0xBob...', // Основатель 2
'0xCarol...' // Инвестор
],
initialAmounts: [
500000, // 50% для Alice
300000, // 30% для Bob
200000 // 20% для Carol
]
};
```
---
## Безопасность смарт-контрактов
### Защита от переводов токенов
**КРИТИЧНО**: Токены управления **НЕЛЬЗЯ** перевести обычными способами!
```solidity
// Переводы ЗАБЛОКИРОВАНЫ
function transfer(address to, uint256 amount)
public
pure
override
returns (bool)
{
revert ErrTransfersDisabled();
}
// Одобрения ЗАБЛОКИРОВАНЫ
function approve(address spender, uint256 amount)
public
pure
override
returns (bool)
{
revert ErrApprovalsDisabled();
}
// TransferFrom ЗАБЛОКИРОВАН
function transferFrom(address from, address to, uint256 amount)
public
pure
override
returns (bool)
{
revert ErrTransfersDisabled();
}
```
**Что это означает**:
- ❌ Невозможно отправить токены на биржу
- ❌ Невозможно продать токены на DEX
- ❌ Невозможно передать токены другому лицу напрямую
- ❌ Злоумышленник НЕ может украсть токены даже со взломанного кошелька
### Единственный способ перевода токенов
**Только через голосование с кворумом:**
```solidity
// Перевод токенов (только через голосование)
function _transferTokens(address recipient, uint256 amount) internal {
require(msg.sender == address(this), "Only through governance");
_transfer(address(this), recipient, amount);
}
```
**Процесс перевода**:
```
1. Создание предложения
├── "Перевести 1000 токенов на адрес 0xNew..."
└── Требуется: минимум 1 токен для создания
2. Голосование
├── Длительность: 1-30 дней (настраивается)
├── Каждый токен = 1 голос
└── Требуется: кворум (например, 10% от всех токенов)
3. Проверка кворума
├── Если "За" > "Против" И кворум достигнут
└── → Предложение одобрено
4. Исполнение
├── Смарт-контракт автоматически переводит токены
└── Событие записано на блокчейне навсегда
```
### Настройка кворума
**Кворум устанавливается при деплое** и может быть изменен только через голосование:
```solidity
uint256 public quorumPercentage; // Например, 10%
function _hasQuorum(uint256 forVotes, uint256 againstVotes)
internal
view
returns (bool)
{
uint256 totalVotes = forVotes + againstVotes;
uint256 required = (totalSupply() * quorumPercentage) / 100;
return totalVotes >= required;
}
```
**Примеры кворума**:
- 5% - легко достичь (для активных организаций)
- 10% - стандартный (рекомендуется)
- 20% - строгий (для критичных решений)
- 51% - абсолютное большинство
### Защита от реентерабельности
```solidity
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
contract DLE is ReentrancyGuard {
function execute(uint256 proposalId)
external
nonReentrant // Защита от реентерабельности
{
// Исполнение предложения
}
}
```
### Защита от flash-loans
**Снапшоты голосов** предотвращают атаки с временным займом токенов:
```solidity
// Голоса берутся из ПРОШЛОГО блока
uint256 public snapshotTimepoint = block.number - 1;
function vote(uint256 proposalId, bool support) external {
// Используем баланс из прошлого блока
uint256 votingPower = getPastVotes(msg.sender, snapshotTimepoint);
require(votingPower > 0, "No voting power");
// Голосование
}
```
**Почему это безопасно**:
1. Злоумышленник берет flash-loan на 1,000,000 токенов
2. Пытается проголосовать
3. Смарт-контракт проверяет баланс в **прошлом блоке**
4. В прошлом блоке у злоумышленника было 0 токенов
5. Голосование отклонено ❌
### Валидация всех параметров
```solidity
// Проверка адресов
if (address == address(0)) revert ErrZeroAddress();
// Проверка наличия токенов
if (balanceOf(msg.sender) == 0) revert ErrNotHolder();
// Проверка длительности голосования
if (duration < minVotingDuration) revert ErrTooShort();
if (duration > maxVotingDuration) revert ErrTooLong();
// Проверка поддерживаемых сетей
if (!supportedChains[chainId]) revert ErrUnsupportedChain();
```
### Custom errors для экономии gas
```solidity
// Экономия gas: custom errors вместо require
error ErrZeroAddress();
error ErrNotHolder();
error ErrAlreadyVoted();
error ErrTransfersDisabled();
error ErrApprovalsDisabled();
error ErrProposalMissing();
error ErrWrongChain();
```
---
## Защита от взлома кошельков
### Сценарий: Злоумышленник получил приватный ключ
**Что может сделать злоумышленник:**
```
Попытки злоумышленника:
1. ❌ Отправить токены на свой адрес
└── БЛОКИРОВАНО: transfer() заблокирован
2. ❌ Продать токены на DEX (Uniswap, etc.)
└── БЛОКИРОВАНО: approve() заблокирован
3. ❌ Отправить через transferFrom
└── БЛОКИРОВАНО: transferFrom() заблокирован
4. ❓ Создать предложение "Перевести токены мне"
└── Требуется голосование других токен-холдеров
└── Кворум: 10%+ должны проголосовать "За"
└── СКОРЕЕ ВСЕГО ПРОВАЛИТСЯ
```
### Реальный пример атаки
```
Злоумышленник взломал кошелек Alice (500,000 токенов):
1. Создает предложение:
"Перевести 500,000 токенов на адрес 0xEvil..."
2. Голосует "За" своими 500,000 голосами (50%)
3. Но кворум = 10% = 100,000 голосов
Уже достигнут? ДА ✅
4. "За" = 500,000 (50%)
"Против" = 0
5. Результат: Предложение ОДОБРЕНО ❌
ПРОБЛЕМА: Если у Alice большинство токенов!
```
### Защита от атаки с большинством токенов
**Решение 1: Timelock Module**
```solidity
// Отложенное исполнение (например, 3 дня)
uint256 public constant TIMELOCK_DELAY = 3 days;
function scheduleProposal(uint256 proposalId) external {
// Предложение одобрено, но исполнится только через 3 дня
executionTime = block.timestamp + TIMELOCK_DELAY;
}
```
**Преимущество**: Другие токен-холдеры видят опасное предложение и могут:
- Проголосовать "Против"
- Создать контр-предложение
- Принять меры (например, обратиться в суд)
**Решение 2: Мультиподпись**
```solidity
// Требуется несколько подписей для критичных операций
mapping(uint256 => mapping(address => bool)) public approvals;
function executeWithApprovals(
uint256 proposalId,
address[] calldata signers,
bytes[] calldata signatures
) external {
// Проверяем подписи нескольких токен-холдеров
require(signers.length >= minSigners, "Not enough signers");
for (uint i = 0; i < signers.length; i++) {
// Проверка подписи
verifySignature(proposalId, signers[i], signatures[i]);
}
// Исполнение
}
```
**Решение 3: Холодный кошелек для крупных холдеров**
Рекомендуется держать токены на:
- 🥶 **Hardware wallet** (Ledger, Trezor) - максимальная защита
- **Мультиподпись** (Gnosis Safe) — требуется несколько подписей
- ❄️ **Холодное хранение** - offline, не подключен к интернету
### Мониторинг подозрительных предложений
**Backend автоматически детектирует опасные предложения:**
```javascript
// Детектор подозрительных предложений
function detectSuspiciousProposal(proposal) {
const alerts = [];
// Проверка 1: Перевод большого количества токенов
if (proposal.operation.includes('_transferTokens')) {
const amount = decodeAmount(proposal.operation);
const percentage = (amount / totalSupply) * 100;
if (percentage > 10) {
alerts.push({
level: 'HIGH',
message: `Предложение переводит ${percentage}% всех токенов!`
});
}
}
// Проверка 2: Инициатор голосует своими токенами
if (proposal.forVotes === proposal.initiatorBalance) {
alerts.push({
level: 'MEDIUM',
message: 'Инициатор голосует только своими токенами'
});
}
// Проверка 3: Быстрое голосование (< 24 часов)
if (proposal.duration < 86400) {
alerts.push({
level: 'MEDIUM',
message: 'Голосование менее 24 часов - мало времени на проверку'
});
}
// Отправляем уведомления всем токен-холдерам
if (alerts.length > 0) {
notifyAllTokenHolders(proposal, alerts);
}
}
```
---
## Безопасность веб-приложения
### Аутентификация через SIWE
**Sign-In with Ethereum** - стандарт безопасной аутентификации:
```javascript
// Генерация nonce (одноразовый)
const nonce = crypto.randomBytes(32).toString('hex');
// Сохранение в БД с шифрованием
await db.query(
'INSERT INTO nonces (address_encrypted, nonce_encrypted, expires_at) VALUES ($1, $2, $3)',
[encrypt(address), encrypt(nonce), expiresAt]
);
// Проверка подписи
const message = new SiweMessage({
domain: req.get('host'),
address: ethers.getAddress(address),
nonce: nonce,
chainId: 1
});
const isValid = await verifySignature(
message.prepareMessage(),
signature,
address
);
```
**Безопасность**:
- ✅ Приватный ключ **никогда** не покидает кошелек
- ✅ Каждый nonce используется **один раз**
- ✅ Nonce истекает через 5 минут
- ✅ Подделать подпись невозможно без приватного ключа
### Шифрование данных
```javascript
// AES-256 шифрование
const crypto = require('crypto');
function encrypt(text, key) {
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
let encrypted = cipher.update(text, 'utf8', 'hex');
encrypted += cipher.final('hex');
return iv.toString('hex') + ':' + encrypted;
}
function decrypt(encrypted, key) {
const parts = encrypted.split(':');
const iv = Buffer.from(parts[0], 'hex');
const encryptedText = parts[1];
const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
let decrypted = decipher.update(encryptedText, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
```
**Что шифруется**:
- Адреса кошельков в БД
- Nonces для аутентификации
- Сессионные данные
- Приватные сообщения
### Rate Limiting
```javascript
const rateLimit = require('express-rate-limit');
// Ограничение запросов
const apiLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 минут
max: 100, // максимум 100 запросов
message: 'Слишком много запросов, попробуйте позже'
});
// Ограничение для аутентификации (более строгое)
const authLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 5, // максимум 5 попыток аутентификации
skipSuccessfulRequests: true
});
app.use('/api/', apiLimiter);
app.use('/api/auth/', authLimiter);
```
### CSRF защита
```javascript
const csrf = require('csurf');
// CSRF токены для всех форм
const csrfProtection = csrf({ cookie: true });
app.post('/api/action', csrfProtection, async (req, res) => {
// Проверка CSRF токена автоматическая
});
```
### XSS защита
```javascript
import DOMPurify from 'dompurify';
// Очистка HTML от опасного кода
function sanitizeHTML(html) {
return DOMPurify.sanitize(html, {
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a', 'p'],
ALLOWED_ATTR: ['href']
});
}
// Использование
const userInput = req.body.comment;
const safeHTML = sanitizeHTML(userInput);
```
### Helmet.js для защиты заголовков
```javascript
const helmet = require('helmet');
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'unsafe-inline'"],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", "data:", "https:"],
}
},
hsts: {
maxAge: 31536000,
includeSubDomains: true,
preload: true
}
}));
```
### Clean Logs система
**Автоматическая очистка логов от чувствительных данных:**
```javascript
function cleanLogs() {
const sensitivePatterns = [
/0x[a-fA-F0-9]{40}/g, // Адреса кошельков
/pk_[a-zA-Z0-9]{64}/g, // Приватные ключи (если случайно залогированы)
/nonce:\s*[a-f0-9]{64}/gi, // Nonces
];
// Замена чувствительных данных на ***
let cleanedLog = logContent;
sensitivePatterns.forEach(pattern => {
cleanedLog = cleanedLog.replace(pattern, '[REDACTED]');
});
return cleanedLog;
}
```
---
## Управление модулями
### Только смарт-контракт DLE управляет модулями
**Модификатор `onlyDLE`** гарантирует, что только смарт-контракт DLE может вызывать функции модуля:
```solidity
// Модуль: TreasuryModule
contract TreasuryModule {
address public immutable dleContract;
modifier onlyDLE() {
require(msg.sender == dleContract, "Only DLE can call");
_;
}
// Только DLE может переводить токены из казны
function transferTokens(
address token,
address recipient,
uint256 amount
) external onlyDLE {
IERC20(token).transfer(recipient, amount);
}
}
```
**Что это означает**:
- ❌ Владелец кошелька **НЕ может** напрямую вызвать функции модуля
- ❌ Backend **НЕ может** вызвать функции модуля
- ❌ Злоумышленник **НЕ может** взаимодействовать с модулем
-**Только** смарт-контракт DLE через голосование
### Процесс использования модуля
```
1. Токен-холдер создает предложение
└── "Перевести 1000 USDC из Treasury на маркетинг"
2. Предложение содержит закодированный вызов функции модуля
└── operation = treasuryModule.transferTokens(USDC, marketing, 1000)
3. Голосование
4. Если одобрено, DLE контракт вызывает модуль:
└── TreasuryModule.transferTokens() ✅
└── msg.sender = DLE контракт ✅
5. Модуль проверяет msg.sender и исполняет
```
### Добавление нового модуля
**Только через голосование:**
```solidity
// Операция добавления модуля
function _addModule(bytes32 moduleId, address moduleAddress) internal {
require(msg.sender == address(this), "Only through voting");
require(moduleAddress != address(0), "Invalid address");
require(!activeModules[moduleId], "Module already exists");
modules[moduleId] = moduleAddress;
activeModules[moduleId] = true;
emit ModuleAdded(moduleId, moduleAddress);
}
```
**Процесс**:
1. Деплой нового модуля
2. Создание предложения: "Добавить модуль X по адресу 0x..."
3. Голосование
4. Если одобрено → модуль добавлен
5. Модуль можно использовать
### Удаление скомпрометированного модуля
Если модуль оказался уязвимым:
```
1. Токен-холдер создает экстренное предложение
└── "Удалить скомпрометированный модуль X"
└── Длительность: 1 день (экстренное голосование)
2. Голосование (ускоренное)
3. Модуль удален
└── Больше нельзя вызвать из DLE контракта
```
---
## Аудит и мониторинг
### Прозрачность на блокчейне
**Все действия записаны навсегда:**
```solidity
// События для аудита
event ProposalCreated(uint256 proposalId, address initiator);
event ProposalVoted(uint256 proposalId, address voter, bool support);
event ProposalExecuted(uint256 proposalId, bytes operation);
event ModuleAdded(bytes32 moduleId, address moduleAddress);
event TokensTransferred(address recipient, uint256 amount);
```
**Проверка в блокчейн-сканере:**
```
https://etherscan.io/address/0xDLE_CONTRACT_ADDRESS
└── Все транзакции видны публично
└── Невозможно скрыть или удалить
```
### Мониторинг в реальном времени
**Backend отслеживает все события:**
```javascript
// Подписка на события смарт-контракта
dleContract.on('ProposalCreated', async (proposalId, initiator, event) => {
logger.info(`Новое предложение #${proposalId} от ${initiator}`);
// Получаем детали предложения
const proposal = await dleContract.proposals(proposalId);
// Анализ безопасности
const risks = analyzeProposalRisks(proposal);
// Уведомление токен-холдеров
if (risks.level === 'HIGH') {
await notifyAllTokenHolders({
type: 'SECURITY_ALERT',
proposalId,
risks
});
}
});
```
### Система алертов
```javascript
// Критичные события требуют немедленного уведомления
const criticalEvents = [
'ProposalCreated', // Новое предложение
'ModuleAdded', // Добавлен модуль
'TokensTransferred' // Переведены токены
];
async function sendAlert(event, data) {
// Email уведомления
await sendEmail({
to: allTokenHolders,
subject: `[DLE Alert] ${event}`,
body: formatAlert(data)
});
// Telegram уведомления
await sendTelegram({
chat: dleNotificationsChat,
message: formatAlert(data)
});
// Запись в логи
logger.warn(`ALERT: ${event}`, data);
}
```
---
## Рекомендации по безопасности
### Для владельцев токенов
1. **Используйте hardware wallet** (Ledger, Trezor)
- Приватный ключ никогда не покидает устройство
- Подтверждение каждой операции на физическом устройстве
2. **Храните seed-фразу безопасно**
- Напишите на бумаге, не храните в цифровом виде
- Используйте металлические пластины для долговечности
- Храните в сейфе или банковской ячейке
3. **Включите уведомления**
- Email алерты на новые предложения
- Telegram боты для критичных событий
4. **Проверяйте все предложения**
- Читайте описание перед голосованием
- Проверяйте адреса получателей
- Используйте timelock для критичных операций
5. **Разделите токены**
- Горячий кошелек: 10-20% для повседневного использования
- Холодный кошелек: 80-90% для долгосрочного хранения
### Для администраторов
1. **Регулярные обновления**
```bash
# Еженедельное обновление
docker-compose pull
docker-compose up -d
```
2. **Резервные копии**
```bash
# Ежедневный бэкап базы данных
docker exec dapp-postgres pg_dump -U user db > backup.sql
```
3. **Мониторинг логов**
```bash
# Проверка логов на подозрительную активность
docker logs dapp-backend | grep -i "error\|warning\|failed"
```
4. **Ротация ключей шифрования**
- Меняйте ключ шифрования раз в год
- Храните старые ключи для расшифровки исторических данных
5. **Firewall настройка**
```bash
# Разрешить только необходимые порты
ufw allow 80/tcp # HTTP
ufw allow 443/tcp # HTTPS
ufw enable
```
### Для разработчиков
1. **✅ Аудит смарт-контрактов**
- Используйте Slither для статического анализа
- Mythril для поиска уязвимостей
- Ручной аудит критичного кода
2. **Тестирование**
```bash
# Запуск тестов
cd backend
yarn test
# Покрытие кода
yarn coverage
```
3. **Код-ревью**
- Все изменения через pull requests
- Минимум 2 ревьюера для критичных изменений
4. **Безопасные зависимости**
```bash
# Проверка уязвимостей
yarn audit
npm audit fix
```
---
## Сценарии атак и защита
### Сценарий 1: Фишинговая атака
**Атака:**
```
1. Злоумышленник создает поддельный сайт: dlle.com (вместо dle.com)
2. Отправляет фишинговые письма токен-холдерам
3. Просит подключить кошелек и подписать транзакцию
```
**Защита:**
```javascript
// Backend проверяет домен в SIWE сообщении
const message = new SiweMessage({
domain: req.get('host'), // Должен быть правильный домен
uri: req.get('origin')
});
// Frontend показывает предупреждение
if (window.location.hostname !== 'dle.app') {
alert('ВНИМАНИЕ: Это НЕ официальный сайт DLE!');
}
```
**Рекомендации пользователям:**
- ✅ Всегда проверяйте URL перед подключением кошелька
- ✅ Используйте закладки браузера
- ✅ Проверяйте SSL сертификат (зеленый замок)
### Сценарий 2: Взлом backend сервера
**Атака:**
```
1. Злоумышленник получает доступ к backend серверу
2. Пытается изменить код для обхода проверки токенов
3. Или полностью выводит веб-приложение из строя
```
**Защита:**
```
✅ Проверка токенов происходит на блокчейне (неизменяемо)
✅ Backend может быть скомпрометирован, но:
├── Невозможно изменить баланс токенов в смарт-контракте
├── Невозможно создать поддельные токены
├── Невозможно изменить правила смарт-контракта
└── Пользователи увидят расхождение между backend и блокчейном
```
**Критично: Веб-приложение - это только интерфейс!**
Даже при **полном взломе** веб-приложения:
- ✅ **Все активы бизнеса защищены** на блокчейне
- ✅ **Смарт-контракты продолжают работать** независимо от веб-приложения
- ✅ **Можно управлять через блокчейн-сканеры** (Etherscan, Polygonscan, и др.)
### Управление через блокчейн-сканеры
**Если веб-приложение недоступно, используйте блокчейн-сканеры:**
#### 1. Проверка баланса токенов
```
1. Откройте Etherscan: https://etherscan.io
2. Введите адрес смарт-контракта DLE
3. Перейдите на вкладку "Read Contract"
4. Вызовите функцию balanceOf(address)
5. Введите адрес вашего кошелька
6. Нажмите "Query" - увидите баланс токенов ✅
```
**Пример**:
```
Contract Address: 0x1234...DLE
Function: balanceOf
Address: 0xYourWallet...
Result: 500000 (ваш баланс токенов)
```
#### 2. Создание предложения через Etherscan
```
1. Откройте Etherscan и найдите смарт-контракт DLE
2. Перейдите на вкладку "Write Contract"
3. Подключите кошелек MetaMask
4. Найдите функцию createProposal
5. Заполните параметры:
- description: "Восстановить веб-приложение"
- operation: закодированный вызов функции
- votingDuration: 86400 (1 день в секундах)
6. Нажмите "Write" и подтвердите транзакцию ✅
```
**Пример создания предложения**:
```solidity
// Через Etherscan Write Contract
createProposal(
"Перевести 10,000 USDT на восстановление инфраструктуры",
0x..., // закодированный вызов transferTokens
86400 // 1 день
)
```
#### 3. Голосование через Etherscan
```
1. Откройте смарт-контракт DLE на Etherscan
2. Вкладка "Write Contract"
3. Подключите кошелек
4. Функция vote(uint256 proposalId, bool support)
- proposalId: номер предложения (например, 5)
- support: true (за) или false (против)
5. Нажмите "Write" ✅
```
#### 4. Проверка состояния предложения
```
1. Вкладка "Read Contract" на Etherscan
2. Функция proposals(uint256)
3. Введите ID предложения
4. Увидите все детали:
- Описание
- Голоса "За" и "Против"
- Статус (Active, Executed, Failed)
- Время окончания голосования
```
#### 5. Исполнение одобренного предложения
```
1. Если предложение одобрено и время истекло
2. Откройте "Write Contract"
3. Функция execute(uint256 proposalId)
4. Введите ID предложения
5. Нажмите "Write" - предложение исполнится ✅
```
### Популярные блокчейн-сканеры для DLE
| Сеть | Блокчейн-сканер | URL |
|------|-----------------|-----|
| **Ethereum Mainnet** | Etherscan | https://etherscan.io |
| **Polygon** | Polygonscan | https://polygonscan.com |
| **Binance Smart Chain** | BscScan | https://bscscan.com |
| **Arbitrum** | Arbiscan | https://arbiscan.io |
| **Optimism** | Optimistic Etherscan | https://optimistic.etherscan.io |
| **Avalanche** | SnowTrace | https://snowtrace.io |
| **Base** | BaseScan | https://basescan.org |
### Преимущества управления через блокчейн-сканеры
**1. Полная независимость от веб-приложения**
```
Веб-приложение взломано → Блокчейн работает ✅
Backend сервер упал → Смарт-контракты работают ✅
Frontend недоступен → Можно управлять через Etherscan ✅
```
**2. Невозможно подделать данные**
```
Злоумышленник на backend → Блокчейн-сканер показывает правду
Поддельный frontend → Etherscan покажет реальные токены
Измененная логика → Смарт-контракт работает как задумано
```
**3. Доступ 24/7 из любой точки мира**
```
Нет доступа к серверу → Etherscan доступен всегда
Приложение на обслуживании → Управление через блокчейн
DDoS атака на сайт → Блокчейн недоступен для DDoS
```
**Реакция на взлом:**
1. Пользователи замечают странное поведение веб-приложения
2. Проверяют баланс токенов напрямую через Etherscan ✅
3. Создают предложение через Etherscan на восстановление
4. Голосуют за восстановление инфраструктуры
5. Администраторы восстанавливают backend из резервной копии
6. **Никакие токены и активы не потеряны** ✅
**Вывод**: Веб-приложение - это лишь удобный интерфейс. Реальная власть и активы находятся на блокчейне, где они защищены криптографией и невозможно их изменить или украсть через взлом веб-приложения.
### Сценарий 3: 51% атака
**Атака:**
```
1. Злоумышленник покупает или получает >51% всех токенов
2. Создает предложение "Перевести все активы мне"
3. Голосует всеми своими токенами "За"
4. Предложение одобрено
```
**Защита:**
```javascript
// Timelock Module дает время на реакцию
const TIMELOCK = 7 days;
// Другие токен-холдеры могут:
1. Проголосовать "Против" (если у них еще 49%)
2. Создать контр-предложение
3. Обратиться в правоохранительные органы
4. Отменить предложение через emergency функцию (если настроена)
```
**Долгосрочная защита:**
- Равномерное распределение токенов между партнерами
- Мультиподпись для крупных операций
- Квадратичное голосование (опция для будущих версий)
### Сценарий 4: Social Engineering
**Атака:**
```
1. Злоумышленник выдает себя за поддержку DLE
2. Просит токен-холдера "для верификации" подписать сообщение
3. Сообщение на самом деле - одобрение перевода токенов
```
**Защита:**
```javascript
// Frontend всегда показывает ЧТО подписывается
function signMessage(message) {
// Показываем пользователю точное содержимое
const confirmation = confirm(`
Вы собираетесь подписать:
${message}
НИКОГДА не подписывайте сообщения по просьбе «поддержки»!
Продолжить?
`);
if (!confirmation) return;
// Подпись
}
```
**Рекомендации:**
- ❌ Поддержка **НИКОГДА** не попросит подписать сообщение
- ❌ Не доверяйте "срочным" запросам
- ✅ Всегда проверяйте, что подписываете
- ✅ При сомнениях - свяжитесь с официальной поддержкой
---
## Заключение
### Многоуровневая защита DLE
```
┌─────────────────────────────────────────────────────┐
│ Уровни безопасности DLE │
├─────────────────────────────────────────────────────┤
│ 1⃣ Блокчейн │
│ └── Токены нельзя украсть даже со взломом │
│ │
│ 2⃣ Смарт-контракты │
│ └── Аудит, OpenZeppelin, иммутабельность │
│ │
│ 3⃣ Голосование с кворумом │
│ └── Невозможно единоличное решение │
│ │
│ 4⃣ Timelock │
│ └── Время на реакцию при атаке │
│ │
│ 5⃣ Backend проверки │
│ └── Проверка токенов в реальном времени │
│ │
│ 6⃣ Frontend защита │
│ └── XSS, CSRF, rate limiting │
│ │
│ 7⃣ Мониторинг и алерты │
│ └── Детекция подозрительных действий │
└─────────────────────────────────────────────────────┘
```
### Ключевые преимущества безопасности
1. **Контроль доступа через токены**
- Без токенов доступ невозможен
- Проверка в реальном времени на блокчейне
2. **Защита от кражи токенов**
- Невозможно перевести без голосования
- Даже при взломе кошелька токены защищены
3. **🌐 Независимость от веб-приложения**
- Даже при взломе веб-приложения активы бизнеса защищены на блокчейне
- Можно управлять через блокчейн-сканеры (Etherscan, Polygonscan и др.)
- Смарт-контракты работают независимо от frontend/backend
- Веб-приложение - это только удобный интерфейс, реальная власть на блокчейне
4. **Коллективное управление**
- Критичные решения только через голосование
- Кворум предотвращает единоличные действия
5. **Модули под контролем смарт-контракта**
- Только DLE контракт может вызывать модули
- Никакого прямого доступа
6. **📊 Полная прозрачность**
- Все действия на блокчейне
- Невозможно скрыть или подделать
### Следующие шаги
1. [Изучите техническую документацию](./back-docs/blockchain-integration-technical.md)
2. [Настройте безопасное окружение](./back-docs/setup-instruction.md)
3. [Прочитайте FAQ](../FAQ.md)
4. [Получите поддержку](https://hb3-accelerator.com/)
---
**© 2024-2025 Тарабанов Александр Викторович. Все права защищены.**
**Последнее обновление**: October 2025