Threat Modeling, STRIDE, OWASP, Security Hardening
Зачем знать на Middle 3: на этом уровне инженер не реактивно патчит уязвимости, а проактивно проектирует системы с учётом моделей угроз. Threat modeling — обязательная часть design review в FAANG, банках, медтехе. STRIDE даёт системный язык, DREAD — оценку. OWASP Top 10 / API Top 10 — must-know. И всё это применяется к Go-сервису через конкретный hardening checklist.
Содержание
Заголовок раздела «Содержание»- Концепция
- Глубже: STRIDE, DREAD, DFD, OWASP 2021, OWASP API
- Gotchas / Best practices
- Real cases
- Вопросы (20)
- Practice
- Источники
1. Концепция
Заголовок раздела «1. Концепция»Threat Modeling: зачем
Заголовок раздела «Threat Modeling: зачем»Threat modeling — структурированный процесс выявления угроз на этапе проектирования. Целевая аудитория ответов:
- Что мы строим? (DFD, диаграммы потоков данных)
- Что может пойти не так? (применяем STRIDE)
- Что мы делаем с этим? (mitigations)
- Хорошо ли мы это сделали? (verification)
Цикл: design → model → mitigate → verify → review.
STRIDE (Microsoft, 1999)
Заголовок раздела «STRIDE (Microsoft, 1999)»Шесть категорий угроз:
| Буква | Угроза | Что нарушает | Пример |
|---|---|---|---|
| Spoofing | подмена identity | Authentication | украденный JWT, фишинг |
| Tampering | модификация данных | Integrity | MITM, изменение БД |
| Repudiation | отказ от действий | Non-repudiation | ”я не делал этот платёж” |
| Information disclosure | утечка данных | Confidentiality | exposed .git, log с PII |
| Denial of service | недоступность | Availability | SYN flood, Slow Loris |
| Elevation of privilege | повышение прав | Authorization | IDOR, sudo exploit |
DREAD (опционально, для скоринга)
Заголовок раздела «DREAD (опционально, для скоринга)»| Буква | Что | Шкала 1-10 |
|---|---|---|
| Damage | насколько серьёзно | 1=минимально, 10=катастрофа |
| Reproducibility | легко повторить | 1=сложно, 10=на лету |
| Exploitability | легко эксплуатировать | 1=PhD нужен, 10=скрипт-кидди |
| Affected users | сколько затронуто | 1=один, 10=все |
| Discoverability | легко найти | 1=скрыто, 10=на главной |
Average → risk score. Сегодня чаще CVSS используют вместо DREAD.
Data Flow Diagram (DFD)
Заголовок раздела «Data Flow Diagram (DFD)»DFD — основа threat modeling. Элементы:
- External entity (квадрат) — пользователь, внешний сервис.
- Process (круг) — наш код.
- Data store (две параллельные линии) — БД, файл, кеш.
- Data flow (стрелка) — поток данных.
- Trust boundary (пунктир) — граница доверия (Internet/intranet, namespace, container).
STRIDE применяется per element type:
- External entity → S, R.
- Process → STRIDE (всё).
- Data store → T, I, D, R.
- Data flow → T, I, D.
2. Глубже
Заголовок раздела «2. Глубже»2.1 Пример: DFD для payment API
Заголовок раздела «2.1 Пример: DFD для payment API» +---------+ HTTPS +---------+ gRPC +---------+ | Browser | ----------> | API | ---------> | Payments| +---------+ <---------- | Gateway | <--------- | Service | +---------+ +---------+ | | | trust boundary | v v +---------+ +---------+ | Redis | | Postgres| | cache | | DB | +---------+ +---------+
Internet | Cluster boundary | Database boundaryПрименяем STRIDE:
| Element | S | T | R | I | D | E |
|---|---|---|---|---|---|---|
| Browser→Gateway | TLS + JWT | TLS | request_id | TLS | rate limit | RBAC |
| Gateway→Payments | mTLS (SPIFFE) | mTLS | audit log | mTLS | timeout | scope |
| Payments→Postgres | DB user + cert | TLS | DB audit | encryption at rest | conn pool | least priv |
| Redis | password | TLS | — | TLS | maxmem policy | ACL |
2.2 OWASP Top 10 (2021) — deeper view
Заголовок раздела «2.2 OWASP Top 10 (2021) — deeper view»A01: Broken Access Control
- IDOR (Insecure Direct Object Reference):
/orders/123доступен без проверки owner. - Mitigation: RBAC/ABAC; subject (user) + resource (object) + action (verb).
- Patterns: middleware с
authz.Allow(user, "read", order). - ABAC: атрибуты + политика (OPA Rego, Cedar).
- ⚠️ Go: писать собственный AuthZ — путь в production with bugs. Используй Casbin / Open Policy Agent.
// Пример: проверка через contextfunc ordersHandler(w http.ResponseWriter, r *http.Request) { userID := r.Context().Value(ctxUserID).(string) orderID := mux.Vars(r)["id"]
order, err := db.GetOrder(r.Context(), orderID) if err != nil { http.Error(w, "not found", 404); return }
if order.OwnerID != userID && !hasRole(userID, "admin") { http.Error(w, "forbidden", 403) return } // ...}A02: Cryptographic Failures
- Использование MD5/SHA1 для passwords (вместо argon2id).
- AES-ECB вместо GCM.
- Hardcoded key.
- TLS 1.0/1.1 (deprecated).
- Mitigation: argon2id / bcrypt для passwords; AES-GCM или ChaCha20-Poly1305 для шифрования; TLS 1.3.
import "golang.org/x/crypto/argon2"
func hashPassword(pass string, salt []byte) []byte { // recommended: time=1, memory=64MiB, threads=4, keyLen=32 return argon2.IDKey([]byte(pass), salt, 1, 64*1024, 4, 32)}A03: Injection
- SQL: используй
db.QueryContext(ctx, "SELECT ... WHERE id=$1", id), никогдаfmt.Sprintf. - Command injection:
exec.Command("sh", "-c", userInput)— НЕТ.exec.Command(bin, args...)— args отдельно. - LDAP, XPath, NoSQL — те же принципы.
- Template injection: Go
html/templateавто-escape. Не используйtext/templateдля HTML.
// Wrongdb.Query(fmt.Sprintf("SELECT * FROM users WHERE name='%s'", name))
// Rightdb.Query("SELECT * FROM users WHERE name=$1", name)A04: Insecure Design
- Отсутствие threat modeling на старте.
- Mitigation: STRIDE per feature; security stories в backlog.
A05: Security Misconfiguration
- Дефолтные пароли (Mongo без auth, Elasticsearch open).
- Debug endpoints в проде (
pprof,/debug). - CORS
*для credentialed endpoints. - Mitigation: CIS benchmarks; IaC review; production lint (kube-bench, kube-score).
// Не выставляй pprof наружуmux := http.NewServeMux()mux.HandleFunc("/api/...", apiHandler)
// Отдельный listener только на localhost для pprofgo http.ListenAndServe("127.0.0.1:6060", nil) // standard net/http/pprofA06: Vulnerable and Outdated Components
- См. файл 39 (Supply Chain).
govulncheck+ SBOM.
A07: Identification and Authentication Failures
- Weak password policy.
- No MFA.
- Predictable session IDs.
- Mitigation: passkey/FIDO2; argon2id; randomness 256-bit для session.
A08: Software and Data Integrity Failures
- Auto-update без signature verification.
- Insecure deserialization (Gob, JSON в неверной структуре, YAML).
- Mitigation: cosign + SLSA; не deserialize в
interface{}без strict schema.
A09: Security Logging and Monitoring Failures
- Нет audit log.
- Log без timestamp/correlation.
- Логирование PII (нарушение GDPR).
- Mitigation: structured logs (zap, zerolog); SIEM (Splunk, Datadog, ELK); redact PII.
A10: Server-Side Request Forgery (SSRF)
- Сервис принимает URL от юзера, делает HTTP запрос.
- Атака:
http://169.254.169.254/latest/meta-data/(AWS IMDS) → утечка credentials. - Mitigation: whitelist hosts; block private IP ranges; IMDSv2 (требует session token).
import "net"
func isPrivate(ip net.IP) bool { privateBlocks := []string{ "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "127.0.0.0/8", "169.254.0.0/16", "::1/128", "fc00::/7", } for _, cidr := range privateBlocks { _, block, _ := net.ParseCIDR(cidr) if block.Contains(ip) { return true } } return false}
func safeFetch(rawURL string) (*http.Response, error) { u, err := url.Parse(rawURL) if err != nil { return nil, err } ips, _ := net.LookupIP(u.Hostname()) for _, ip := range ips { if isPrivate(ip) { return nil, errors.New("private IP blocked") } } // ⚠️ DNS rebinding: проверяем IP в Dialer too cl := &http.Client{ Transport: &http.Transport{ DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { host, port, _ := net.SplitHostPort(addr) ips, _ := net.LookupIP(host) for _, ip := range ips { if isPrivate(ip) { return nil, errors.New("blocked") } } return (&net.Dialer{}).DialContext(ctx, network, addr) }, }, Timeout: 5 * time.Second, } return cl.Get(rawURL)}2.3 OWASP API Security Top 10 (2023)
Заголовок раздела «2.3 OWASP API Security Top 10 (2023)»API-specific риски:
- BOLA (Broken Object Level Auth) — IDOR.
- Broken Authentication — слабая JWT валидация.
- Broken Object Property Level Auth — overposting (юзер шлёт
is_admin=trueв PUT). - Unrestricted Resource Consumption — нет rate limit, pagination.
- BFLA (Broken Function Level Auth) — нет проверки role per endpoint.
- Unrestricted Access to Sensitive Business Flows — auto-checkout без CAPTCHA.
- SSRF.
- Security Misconfiguration.
- Improper Inventory Management — забытые legacy /v1.
- Unsafe Consumption of APIs — слепое доверие сторонним.
2.4 Hardening checklist для Go-сервиса
Заголовок раздела «2.4 Hardening checklist для Go-сервиса»Code level:
- Read-only filesystem где можно (
/tmpwritable). - Run as non-root:
USER 65532:65532в Dockerfile. - Drop capabilities:
securityContext.capabilities.drop: ["ALL"]. - AppArmor/SELinux profile.
goseclint в CI.govulncheckв CI.staticcheck,go vet.
TLS:
- TLS 1.3 only где возможно.
- HSTS header.
- mTLS internal.
HTTP:
- Secure headers (CSP, X-Frame-Options, X-Content-Type-Options).
- Rate limit (token bucket per IP + per user).
- Request size limit (
http.MaxBytesReader). - Timeouts: ReadHeaderTimeout, ReadTimeout, WriteTimeout, IdleTimeout.
srv := &http.Server{ Addr: ":8443", ReadHeaderTimeout: 5 * time.Second, ReadTimeout: 30 * time.Second, WriteTimeout: 30 * time.Second, IdleTimeout: 120 * time.Second, MaxHeaderBytes: 1 << 20, // 1 MB Handler: secureHeaders(rateLimiter(handler)),}Logging:
- Structured (JSON).
- Correlation ID per request.
- No secrets/PII (redact).
- Audit log (separate stream, immutable).
Configuration:
- Secrets через Vault / env (не git).
- Feature flags для emergency disable.
- Health/readiness отдельно от business endpoints.
Container:
- Distroless / scratch.
- Pin by digest.
- Sign + verify (cosign).
- Resource limits (CPU, memory).
- Network policy (deny by default).
- Read-only root FS, writable emptyDir для cache.
Kubernetes:
runAsNonRoot: true.allowPrivilegeEscalation: false.readOnlyRootFilesystem: true.- PodSecurityStandards “restricted”.
- PSA (Pod Security Admission) enforce.
2.5 Инструменты Threat Modeling
Заголовок раздела «2.5 Инструменты Threat Modeling»- Microsoft Threat Modeling Tool (Windows, бесплатный).
- OWASP Threat Dragon (open-source, web).
- IriusRisk (enterprise).
- ThreatSpec — Go-friendly, threats в комментариях кода:
// @threat ssrf:SSRF "Server-Side Request Forgery"// @control validate_url:strictUrlValidator// @asset internal_metadata "EC2 instance metadata"func fetchURL(url string) ([]byte, error) { // ...}3. Gotchas / Best practices
Заголовок раздела «3. Gotchas / Best practices»⚠️ CORS Access-Control-Allow-Origin: * + credentials — браузер блокирует, но многие думают, что “стало работать”; не проверяй wildcard для cookies.
⚠️ JWT alg: none — старый, но всё ещё встречаемый bug. В Go явно whitelist’и RS256/ES256. Не используй jwt.Parse без keyFunc, явно проверяющего Method.
⚠️ bcrypt cost — увеличивать каждые пару лет (сейчас 12+).
⚠️ Argon2 параметры — не дефолтные. memory >= 64MB, threads = num_cores.
⚠️ Time-based comparison — пароли/HMAC сравнивать через subtle.ConstantTimeCompare, не bytes.Equal.
⚠️ math/rand — НЕ для криптографии. Использовать crypto/rand.
⚠️ Go 1.20+ — math/rand auto-seeded, но всё равно не cryptographic.
⚠️ http.MaxBytesReader — ставь на тело запроса; иначе атакующий зальёт гигабайты.
⚠️ Reflection в JSON unmarshalling — поля без тегов exporten, могут попасть в overposting. Используй DTO-структуры.
⚠️ io.Copy без io.LimitReader — DoS через гигабайтный ответ от внешнего API.
⚠️ Cookie без HttpOnly + Secure + SameSite=Lax/Strict — XSS уведёт сессию.
⚠️ CSP unsafe-inline — фактически отключает защиту от XSS. Используй nonce.
⚠️ pprof endpoint — net/http/pprof авто-регистрит в DefaultServeMux. На дефолтном http.ListenAndServe(":80", nil) будет наружу.
⚠️ Path traversal: filepath.Join("uploads", userPath) НЕ защищает. Используй filepath.Clean + проверку префикса.
clean := filepath.Clean(filepath.Join(baseDir, userPath))if !strings.HasPrefix(clean, baseDir) { return errors.New("path traversal")}⚠️ Race в JWT cache: проверка sig + claims должны быть атомарны с blacklist check.
Best practices
Заголовок раздела «Best practices»- Threat modeling в каждом design review.
- Security stories в backlog с явным acceptance criteria.
- Bug bounty или внутренний red team.
- Tabletop exercises — учения по incident response.
- Postmortem для security incidents (no-blame).
- Continuous threat modeling при изменении архитектуры.
4. Real cases
Заголовок раздела «4. Real cases»4.1 Capital One breach (2019)
Заголовок раздела «4.1 Capital One breach (2019)»SSRF в WAF (ModSecurity) → атакующий получил IMDS креды → доступ к S3 buckets с 100M записями.
Mitigation:
- IMDSv2 (session token).
- WAF threat modeling — обработка пользовательских URL.
4.2 Equifax (2017)
Заголовок раздела «4.2 Equifax (2017)»Apache Struts CVE-2017-5638 (RCE), не пропатчили вовремя. 147M PII утекло.
Mitigation:
- SBOM + vuln scanning.
- SLA на patch critical vulnerabilities (24-48h).
4.3 Travis CI secrets leak (2021)
Заголовок раздела «4.3 Travis CI secrets leak (2021)»Public repos получали env (включая AWS creds) в forked PR builds.
Mitigation:
- Ephemeral OIDC tokens вместо long-lived secrets (Sigstore, AWS OIDC).
- Mask secrets в логах.
4.4 Replit Bounty (2023)
Заголовок раздела «4.4 Replit Bounty (2023)»В Replit обнаружили IDOR в API: /api/projects/{id} отдавал чужие проекты при правильном UUID.
Lesson: always validate ownership даже когда ID “unguessable”.
4.5 Кейс банка: tabletop exercise
Заголовок раздела «4.5 Кейс банка: tabletop exercise»Симуляция: “что если 1 dev украдёт production credentials и удалит DB”. Выявили:
- Нет 4-eyes review на критичные операции.
- Нет audit log.
- Backup живёт в том же AWS аккаунте → удалят и его.
Mitigation: separate audit account, MFA для prod, vault session с записью.
5. Вопросы (20)
Заголовок раздела «5. Вопросы (20)»- Что такое STRIDE и какие категории угроз?
- Чем DFD отличается от architecture diagram?
- Какие угрозы применимы к “data store” по STRIDE?
- DREAD vs CVSS — что выбрать в 2026?
- Опиши IDOR. Как защититься?
- RBAC vs ABAC — разница и когда что выбрать?
- Как защититься от SSRF в Go-сервисе, принимающем URL?
- Что такое DNS rebinding и почему он опасен для SSRF-защиты?
- Почему
bytes.Equalнельзя для сравнения секретов? - Чем argon2id лучше bcrypt?
- Что не так с JWT
alg: none? - CSP
unsafe-inline— почему это плохо? - Чем PSA отличается от PSP в Kubernetes?
- Как назначить distroless image read-only filesystem в k8s?
- Где допустимо
text/templateи где обязательноhtml/template? - Что такое overposting и как защититься?
- Чем audit log отличается от обычного log?
- Какие taймouts обязательны для
http.Server? math/randvscrypto/rand— где что использовать?- Как организовать threat modeling процесс в команде?
6. Practice
Заголовок раздела «6. Practice»- Возьми существующий Go-сервис, нарисуй DFD (Mermaid или draw.io), примени STRIDE.
- Реализуй SSRF-safe HTTP client (с защитой от DNS rebinding).
- Напиши middleware для secure headers (CSP, HSTS, X-Frame-Options).
- Внедри Casbin или OPA для RBAC, покрой 5 endpoints policies.
- Argon2id password hashing + verification (с константным временем).
- Audit log: события
auth.success,auth.fail,resource.accessв отдельный поток. - Запусти
gosecна проекте, разбери top 10 issues. - Настрой PSA “restricted” namespace, попробуй задеплоить root container — должно отвергнуться.
- Mini-tabletop exercise: симулируй компрометацию dev машины, оцени blast radius.
7. Источники
Заголовок раздела «7. Источники»- STRIDE — Microsoft (1999), Adam Shostack
- “Threat Modeling: Designing for Security” — Adam Shostack
- OWASP Top 10 (2021): https://owasp.org/Top10/
- OWASP API Security Top 10 (2023)
- OWASP Cheat Sheet Series
- NIST SP 800-30 — Guide for Conducting Risk Assessments
- CIS Kubernetes Benchmark
- Microsoft Threat Modeling Tool docs
- OWASP Threat Dragon: https://owasp.org/www-project-threat-dragon/
- ThreatSpec: https://threatspec.org
- Capital One breach post-mortem
- Equifax breach Senate report
- xz-utils backdoor analysis (2024)
- AWS Well-Architected — Security Pillar
- Google SRE Security Workbook
- “Web Application Hacker’s Handbook” — Stuttard, Pinto
gosec(Go security checker): https://github.com/securego/gosec- Open Policy Agent: https://www.openpolicyagent.org
- Casbin: https://casbin.org
- CWE database: https://cwe.mitre.org