Принцип наименьших привилегий
Принцип наименьших привилегий (Least Privilege / PoLP) — каждый компонент системы (пользователь, процесс, сервис) должен иметь только те права, которые минимально необходимы для выполнения его функций, и не более того.
Зачем нужно
Если скомпрометирован компонент с избыточными правами, атака распространяется на всю систему. Ограничение прав минимизирует радиус поражения: взломанный read-only пользователь БД не позволит удалить данные; сервис без доступа к S3 не сольёт файлы.
Где используется
- Права пользователей в приложении (роли: admin / editor / viewer)
- БД-пользователи: отдельные учётные записи для каждого сервиса
- IAM-политики в AWS/GCP/Azure
- Docker-контейнеры: запуск без root
- SSH-доступ и серверные пользователи
Основной контент
Роли в приложении (RBAC)
// Ролевая модель вместо флага isAdmin
const PERMISSIONS = {
admin: ['read', 'write', 'delete', 'manage_users'],
editor: ['read', 'write'],
viewer: ['read'],
};
function hasPermission(userRole, action) {
return PERMISSIONS[userRole]?.includes(action) ?? false;
}
// Middleware
function requirePermission(action) {
return (req, res, next) => {
if (!hasPermission(req.user.role, action)) {
return res.status(403).json({ error: 'Insufficient permissions' });
}
next;
};
}
app.delete('/api/posts/:id', authenticate, requirePermission('delete'), deletePost);
БД: минимальные права для каждого сервиса
-- Отдельный пользователь для каждого сервиса
CREATE USER api_service WITH PASSWORD 'strong_password';
GRANT SELECT, INSERT, UPDATE ON orders, users TO api_service;
-- НЕТ прав на DELETE, DROP, TRUNCATE
CREATE USER reports_service WITH PASSWORD 'another_password';
GRANT SELECT ON ALL TABLES IN SCHEMA public TO reports_service;
-- Только чтение
AWS IAM: минимальные политики
{
"Statement": [{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::my-uploads-bucket/*"
// Только конкретный бакет, только Get/Put — не Delete, не ListBuckets
}]
}
Docker: без root
FROM node:20-alpine
# Создаём непривилегированного пользователя
RUN addgroup -g 1001 appgroup && adduser -u 1001 -G appgroup -s /bin/sh -D appuser
WORKDIR /app
COPY --chown=appuser:appgroup . .
RUN npm ci --only=production
USER appuser # Запуск от непривилегированного пользователя
EXPOSE 3000
CMD ["node", "server.js"]
Node.js: минимальные права процесса
# Запуск на порту 80 без root через capabilities
setcap 'cap_net_bind_service=+ep' /usr/local/bin/node
# Или через nginx reverse proxy (рекомендуется):
# Node на порту 3000 (без root), nginx на 80/443 с proxy_pass
Частые ошибки
- Один суперпользователь БД для всего приложения — взлом одного сервиса даёт полный доступ
- Запуск Docker-контейнеров от root —
docker run --privilegedкатастрофически опасен - IAM-политики с
"Action": "*", "Resource": "*"— даёт полный доступ к облаку - "Временные" расширенные права, которые никто не убирает
Связанные темы
- _MOC Безопасность
- Broken Access Control
- Секреты -- .env и переменные окружения
- Secure SDLC -- безопасный жизненный цикл