AGENT SKILL

security

Security — чеклист безопасности Go-сервисов: валидация входа, секреты, auth, CVE-зависимости. Используй при правке auth-middleware, обработке user input, внешних вызовах, или как чеклист в /go-review.

License 许可
MIT
最近更新
2026-11-05
Stars
★ 7
Forks
1

01 前言 Front Matter

name
security
description
Security — чеклист безопасности Go-сервисов: валидация входа, секреты, auth, CVE-зависимости. Используй при правке auth-middleware, обработке user input, внешних вызовах, или как чеклист в /go-review.

03 SKILL.md 正文

Security — безопасность vmkteam Go-сервисов

Справочник по безопасности для vmkteam-стека: JSON-RPC API, go-pg, zenrpc, auth middleware. Используется автоматически при code review (/go-review) и разработке (/solve).

Инструменты

Инструмент Что ищет Команда
gosec SQL injection, hardcoded credentials, weak crypto, command injection gosec ./...
govulncheck Уязвимости в зависимостях (только реально используемые функции) govulncheck ./...
gitleaks API keys, tokens, passwords в коде и git-истории gitleaks detect --source .
trivy Уязвимости в Docker-образах CI only

SQL Injection

Главная точка риска — _repo_ext.go (кастомные запросы).

Плохо — пользовательский ввод в raw SQL:

// УЯЗВИМО: searchText попадает в SQL напрямую
func (r OrderRepo) SearchOrders(ctx context.Context, searchText string) ([]Order, error) {
    var orders []Order
    _, err := r.db.Query(&orders,
        "SELECT * FROM orders WHERE title LIKE '%"+searchText+"%'", nil)
    return orders, err
}

Хорошо — параметризованный запрос через go-pg:

func (r OrderRepo) SearchOrders(ctx context.Context, searchText string) ([]Order, error) {
    var orders []Order
    err := r.db.Model(&orders).
        Where("title ILIKE ?", "%"+searchText+"%").
        Select()
    return orders, err
}

Хорошо — если нужен raw SQL, использовать pg.SafeQuery:

q := r.db.Model(&orders)
q = q.Where("? ILIKE ?", pg.Ident("title"), "%"+searchText+"%")

Правило: go-pg ORM экранирует автоматически. Опасность только в Query() с конкатенацией строк.

Аутентификация и авторизация

Auth middleware (типичная ошибка — IDOR)

Middleware проверяет аутентификацию (есть ли валидный токен), но не авторизацию (может ли этот пользователь делать это действие).

Плохо — middleware пропустил, но метод не проверяет ownership:

func (s OrderService) GetByID(ctx context.Context, id int) (*Order, error) {
    // Любой авторизованный пользователь может получить любой заказ
    return s.repo.OrderByID(ctx, id)
}

Хорошо — проверка ownership:

func (s OrderService) GetByID(ctx context.Context, id int) (*Order, error) {
    user := UserFromContext(ctx)
    order, err := s.repo.OrderByID(ctx, id)
    if err != nil {
        return nil, newInternalError(err)
    }
    if order == nil {
        return nil, ErrNotFound
    }
    if order.UserID != user.ID {
        return nil, ErrForbidden
    }
    return NewOrder(order), nil
}

Auth whitelist

В server.go middleware пропускает определённые методы без авторизации. Whitelist должен быть минимальным:

// Только auth.Login не требует токен
if ns == NSAuth && method == RPC.AuthService.Login {
    return h(ctx, method, params)
}

Error Information Leakage

zenrpc.NewError(code, err) кладёт err.Error() в message ответа. Для кода 500 (и отрицательных) это безопасно только благодаря middleware: zm.WithErrorSLog (legacy — zm.WithErrorLogger) логирует такую ошибку, отправляет её в Sentry и заменяет message на "Internal error". Для остальных кодов маскировки нет.

Хорошо — внутренняя ошибка: причина уходит в Sentry, клиент видит "Internal error":

func newInternalError(err error) *zenrpc.Error {
    return zenrpc.NewError(http.StatusInternalServerError, err)
}

return nil, newInternalError(err)

Работает, только если zm.WithErrorSLog есть в rpc.Use(...) в server.go — без него клиент получит текст ошибки.

Хорошо — клиентская ошибка с фиксированным текстом:

var ErrNotFound = zenrpc.NewStringError(http.StatusNotFound, "not found")

Плохо — NewError с кодом 4xx: текст внутренней ошибки уходит клиенту как есть:

return nil, zenrpc.NewError(http.StatusBadRequest, err)
// Клиент увидит: {"error":{"code":400,"message":"pq: relation \"orders\" does not exist"}}

Плохо — zenrpc.NewStringError(500, "internal error") вместо newInternalError(err): клиенту безопасно, но в Sentry уходит строка без причины, и диагностировать нечем.

Sensitive Data in Logs

zenrpc-middleware (WithSLog, WithAPILogger) логирует параметры запросов. Если метод принимает пароль — он попадёт в логи.

Решение: не передавать секреты как RPC-параметры, или фильтровать в middleware.

JSON-RPC специфика

  • Все методы через один POST endpoint (/rpc/) — стандартные WAF-правила для REST не работают
  • Rate limiting на уровне reverse proxy (traefik/nginx) — по IP, не по методу
  • CORS: AllowOrigins: []string{"*"} допустим в dev, но в production ограничивать доменами

Чеклист для code review

Категория Проверить
SQL Нет конкатенации строк в _repo_ext.go
Auth Whitelist методов минимальный
Authz Проверка ownership/прав внутри методов (не только middleware)
Validation Все входы через go-playground/validator, max длины строк
Errors 4xx — NewStringError с фиксированным текстом; 500 — newInternalError(err), и в цепочке middleware есть zm.WithErrorSLog
Logging Пароли/токены не в параметрах логируемых методов
Secrets cfg/local.toml в .gitignore, нет hardcoded credentials
CORS Ограничен в production

04 同仓库更多 Skills

vmkteam
vmkteam/claude-plugins

zenrpc

Zenrpc — справочник по JSON-RPC 2.0 серверу для Go. Используй при создании и редактировании RPC-сервисов.

★ 7
vmkteam
vmkteam/claude-plugins

youtrack

YouTrack — задачи через REST API и pcurl. Используй для поиска issues, создания, обновления описаний, смены assignee/stage/приоритета, логирования времени и работы с комментариями.

★ 7
vmkteam
vmkteam/claude-plugins

topsrv

topsrv — метрики, алерты, CVE и HTTP-логи серверов проекта через публичный JSON-RPC API app.topsrv.io. Используй, когда нужна загрузка CPU, памяти или диска хоста, метрики PostgreSQL/nginx/angie агента topsrv (`topsrv_*`), какие алерты горят, уязвимые пакеты на серверах или кто (боты, сети, IP) нагружает сайт.

★ 7
vmkteam
vmkteam/claude-plugins

testing

Testing — используй всегда, когда пишешь или правишь Go-тесты (*_test.go), в том числе по сценариям Given/When/Then из spec: фреймворк как в соседних файлах, префикс TestDB, фабрики pkg/db/test, реальная БД без моков. Также при настройке TestMain/test-short и когда тесты падают в gate, но проходят локально.

测试与质量
★ 7
vmkteam
vmkteam/claude-plugins

solve

Solve — полный цикл решения задачи из YouTrack: preflight → анализ → план → реализация → ревью → коммит. Используй при любой YouTrack-задаче (`/solve PLF-819`); флаг `--fast` сокращает HITL для тривиальных багфиксов.

★ 7
vmkteam
vmkteam/claude-plugins

skills-check

Skills Check — smoke-тесты интеграций из project-index.md. Используй для проверки что pcurl-профили и URL всех data-source скиллов ещё живы.

★ 7