ndomo 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (247) hide show
  1. package/.bun-version +1 -0
  2. package/.dockerignore +79 -0
  3. package/.editorconfig +18 -0
  4. package/.env.example +19 -0
  5. package/.github/CODEOWNERS +8 -0
  6. package/.github/ISSUE_TEMPLATE/bug_report.yml +62 -0
  7. package/.github/ISSUE_TEMPLATE/config.yml +2 -0
  8. package/.github/ISSUE_TEMPLATE/feature_request.yml +34 -0
  9. package/.github/dependabot.yml +36 -0
  10. package/.github/pull_request_template.md +24 -0
  11. package/.github/release.yml +30 -0
  12. package/.github/workflows/gitleaks.yml +28 -0
  13. package/.github/workflows/release-please.yml +27 -0
  14. package/.github/workflows/smoke.yml +29 -0
  15. package/.husky/commit-msg +1 -0
  16. package/CHANGELOG.md +114 -0
  17. package/Dockerfile +32 -0
  18. package/README.es.md +174 -0
  19. package/README.md +187 -0
  20. package/agents/chronicler.md +98 -0
  21. package/agents/ci-smith.md +136 -0
  22. package/agents/craftsman.md +341 -0
  23. package/agents/deploy-smith.md +138 -0
  24. package/agents/foreman.md +377 -0
  25. package/agents/go-smith.md +164 -0
  26. package/agents/guild.md +188 -0
  27. package/agents/inspector.md +83 -0
  28. package/agents/js-smith.md +127 -0
  29. package/agents/ops-scout.md +173 -0
  30. package/agents/painter.md +200 -0
  31. package/agents/python-smith.md +120 -0
  32. package/agents/ranger.md +307 -0
  33. package/agents/release-smith.md +165 -0
  34. package/agents/rust-smith.md +159 -0
  35. package/agents/sage.md +178 -0
  36. package/agents/scout.md +144 -0
  37. package/agents/scribe.md +156 -0
  38. package/agents/smith.md +201 -0
  39. package/agents/vue-smith.md +155 -0
  40. package/agents/warden.md +216 -0
  41. package/agents/zig-smith.md +156 -0
  42. package/bin/ndomo-analyses.ts +4 -0
  43. package/bin/ndomo-status.ts +4 -0
  44. package/biome.json +57 -0
  45. package/bun.lock +514 -0
  46. package/commitlint.config.js +3 -0
  47. package/config/ndomo.config.json +258 -0
  48. package/config/ndomo.schema.json +166 -0
  49. package/docs/agents.md +375 -0
  50. package/docs/bugs/plan-create-orphan-fk.md +131 -0
  51. package/docs/bugs/task_create_batch-order-index-collision.md +158 -0
  52. package/docs/configuration.md +276 -0
  53. package/docs/database.md +364 -0
  54. package/docs/features/feature-flexible-builder-v1.md +724 -0
  55. package/docs/features/feature-flexible-builder-v2.md +882 -0
  56. package/docs/features/feature-flexible-builder.md +974 -0
  57. package/docs/http-server.md +244 -0
  58. package/docs/installation.md +259 -0
  59. package/docs/integrations.md +129 -0
  60. package/docs/operations/anti-pattern-sub-agent-verify-2026-06-21.md +32 -0
  61. package/docs/operations/audit-v1.md +417 -0
  62. package/docs/operations/audit-v2.md +197 -0
  63. package/docs/operations/audit-v3.md +306 -0
  64. package/docs/operations/db-optimize-foundations.md +123 -0
  65. package/docs/operations/verify-gate-architecture.md +82 -0
  66. package/docs/workflows.md +448 -0
  67. package/opencode.json +5 -0
  68. package/package.json +65 -0
  69. package/release-please-config.json +11 -0
  70. package/scripts/dev-bust-cache.sh +164 -0
  71. package/scripts/install.sh +688 -0
  72. package/scripts/smoke-e2e.ts +704 -0
  73. package/scripts/smoke-hot.ts +417 -0
  74. package/scripts/smoke-http.sh +228 -0
  75. package/scripts/smoke-v4.ts +256 -0
  76. package/scripts/smoke-v5.ts +397 -0
  77. package/scripts/smoke.sh +9 -0
  78. package/scripts/uninstall.sh +224 -0
  79. package/skills/api-security-best-practices/SKILL.md +915 -0
  80. package/skills/bash-scripting/SKILL.md +201 -0
  81. package/skills/bun/SKILL.md +313 -0
  82. package/skills/cavecrew/SKILL.md +82 -0
  83. package/skills/caveman/SKILL.md +74 -0
  84. package/skills/caveman-review/README.md +33 -0
  85. package/skills/caveman-review/SKILL.md +55 -0
  86. package/skills/find-skills/SKILL.md +142 -0
  87. package/skills/frontend-design/LICENSE.txt +177 -0
  88. package/skills/frontend-design/SKILL.md +55 -0
  89. package/skills/golang-patterns/SKILL.md +674 -0
  90. package/skills/golang-security/SKILL.md +185 -0
  91. package/skills/golang-security/evals/evals.json +595 -0
  92. package/skills/golang-security/references/architecture.md +268 -0
  93. package/skills/golang-security/references/checklist.md +80 -0
  94. package/skills/golang-security/references/cookies.md +200 -0
  95. package/skills/golang-security/references/cryptography.md +424 -0
  96. package/skills/golang-security/references/filesystem.md +285 -0
  97. package/skills/golang-security/references/injection.md +315 -0
  98. package/skills/golang-security/references/logging.md +163 -0
  99. package/skills/golang-security/references/memory-safety.md +241 -0
  100. package/skills/golang-security/references/network.md +253 -0
  101. package/skills/golang-security/references/secrets.md +189 -0
  102. package/skills/golang-security/references/third-party.md +159 -0
  103. package/skills/golang-security/references/threat-modeling.md +189 -0
  104. package/skills/golang-testing/SKILL.md +720 -0
  105. package/skills/grill-me/SKILL.md +7 -0
  106. package/skills/javascript-testing-patterns/SKILL.md +537 -0
  107. package/skills/javascript-testing-patterns/references/advanced-testing-patterns.md +513 -0
  108. package/skills/modern-javascript-patterns/SKILL.md +43 -0
  109. package/skills/modern-javascript-patterns/references/advanced-patterns.md +487 -0
  110. package/skills/modern-javascript-patterns/references/details.md +457 -0
  111. package/skills/python-anti-patterns/SKILL.md +349 -0
  112. package/skills/python-design-patterns/SKILL.md +85 -0
  113. package/skills/python-design-patterns/references/details.md +353 -0
  114. package/skills/python-error-handling/SKILL.md +193 -0
  115. package/skills/python-error-handling/references/details.md +171 -0
  116. package/skills/python-testing-patterns/SKILL.md +278 -0
  117. package/skills/python-testing-patterns/references/advanced-patterns.md +411 -0
  118. package/skills/python-testing-patterns/references/details.md +349 -0
  119. package/skills/rust-patterns/SKILL.md +500 -0
  120. package/skills/rust-testing/SKILL.md +501 -0
  121. package/skills/security-review/SKILL.md +504 -0
  122. package/skills/security-review/cloud-infrastructure-security.md +361 -0
  123. package/skills/vue-best-practices/SKILL.md +154 -0
  124. package/skills/vue-best-practices/references/animation-class-based-technique.md +254 -0
  125. package/skills/vue-best-practices/references/animation-state-driven-technique.md +291 -0
  126. package/skills/vue-best-practices/references/component-async.md +97 -0
  127. package/skills/vue-best-practices/references/component-data-flow.md +307 -0
  128. package/skills/vue-best-practices/references/component-fallthrough-attrs.md +174 -0
  129. package/skills/vue-best-practices/references/component-keep-alive.md +137 -0
  130. package/skills/vue-best-practices/references/component-slots.md +216 -0
  131. package/skills/vue-best-practices/references/component-suspense.md +228 -0
  132. package/skills/vue-best-practices/references/component-teleport.md +108 -0
  133. package/skills/vue-best-practices/references/component-transition-group.md +128 -0
  134. package/skills/vue-best-practices/references/component-transition.md +125 -0
  135. package/skills/vue-best-practices/references/composables.md +290 -0
  136. package/skills/vue-best-practices/references/directives.md +162 -0
  137. package/skills/vue-best-practices/references/perf-avoid-component-abstraction-in-lists.md +159 -0
  138. package/skills/vue-best-practices/references/perf-v-once-v-memo-directives.md +182 -0
  139. package/skills/vue-best-practices/references/perf-virtualize-large-lists.md +187 -0
  140. package/skills/vue-best-practices/references/plugins.md +166 -0
  141. package/skills/vue-best-practices/references/reactivity.md +344 -0
  142. package/skills/vue-best-practices/references/render-functions.md +201 -0
  143. package/skills/vue-best-practices/references/sfc.md +310 -0
  144. package/skills/vue-best-practices/references/state-management.md +135 -0
  145. package/skills/vue-best-practices/references/updated-hook-performance.md +187 -0
  146. package/skills/vue-pinia-best-practices/SKILL.md +21 -0
  147. package/skills/vue-pinia-best-practices/reference/pinia-no-active-pinia-error.md +248 -0
  148. package/skills/vue-pinia-best-practices/reference/pinia-setup-store-return-all-state.md +227 -0
  149. package/skills/vue-pinia-best-practices/reference/pinia-store-destructuring-breaks-reactivity.md +193 -0
  150. package/skills/vue-pinia-best-practices/reference/state-url-for-ephemeral-filters.md +238 -0
  151. package/skills/vue-pinia-best-practices/reference/state-use-pinia-for-large-apps.md +262 -0
  152. package/skills/vue-pinia-best-practices/reference/store-method-binding-parentheses.md +191 -0
  153. package/skills/zig-0.16/SKILL.md +840 -0
  154. package/skills/zig-0.16/scripts/check-zig-version.sh +21 -0
  155. package/src/cli/analyses.ts +280 -0
  156. package/src/cli/index.ts +108 -0
  157. package/src/cli/serve.ts +192 -0
  158. package/src/cli/smoke.ts +131 -0
  159. package/src/cli/status.test.ts +204 -0
  160. package/src/cli/status.ts +263 -0
  161. package/src/cli/vacuum.test.ts +82 -0
  162. package/src/cli/vacuum.ts +96 -0
  163. package/src/config/schema.test.ts +88 -0
  164. package/src/config/schema.ts +64 -0
  165. package/src/db/analyses-migration.test.ts +210 -0
  166. package/src/db/analyses.test.ts +466 -0
  167. package/src/db/analyses.ts +375 -0
  168. package/src/db/auto-checkpoint.ts +131 -0
  169. package/src/db/client.test.ts +129 -0
  170. package/src/db/client.ts +55 -0
  171. package/src/db/fts-escape.ts +20 -0
  172. package/src/db/incidents.test.ts +201 -0
  173. package/src/db/incidents.ts +93 -0
  174. package/src/db/index.ts +86 -0
  175. package/src/db/migrations-v13.test.ts +141 -0
  176. package/src/db/migrations-v8.test.ts +301 -0
  177. package/src/db/migrations.ts +147 -0
  178. package/src/db/plan-archive.test.ts +180 -0
  179. package/src/db/plan-archive.ts +274 -0
  180. package/src/db/plan-create.test.ts +276 -0
  181. package/src/db/plan-create.ts +78 -0
  182. package/src/db/plan-files.test.ts +289 -0
  183. package/src/db/plan-update-status.ts +287 -0
  184. package/src/db/plans.test.ts +490 -0
  185. package/src/db/plans.ts +534 -0
  186. package/src/db/resolve-project-dir.test.ts +143 -0
  187. package/src/db/resolve-project-dir.ts +75 -0
  188. package/src/db/rollbacks.test.ts +150 -0
  189. package/src/db/rollbacks.ts +67 -0
  190. package/src/db/schema.ts +907 -0
  191. package/src/db/sessions.test.ts +80 -0
  192. package/src/db/sessions.ts +135 -0
  193. package/src/db/shutdown.test.ts +147 -0
  194. package/src/db/shutdown.ts +45 -0
  195. package/src/db/tasks.test.ts +921 -0
  196. package/src/db/tasks.ts +747 -0
  197. package/src/db/types.ts +619 -0
  198. package/src/http/__tests__/auth.test.ts +196 -0
  199. package/src/http/__tests__/routes.test.ts +465 -0
  200. package/src/http/__tests__/sse.test.ts +317 -0
  201. package/src/http/auth.ts +72 -0
  202. package/src/http/middleware/cors.ts +53 -0
  203. package/src/http/middleware/security-headers.ts +21 -0
  204. package/src/http/routes/events.ts +112 -0
  205. package/src/http/routes/health.ts +51 -0
  206. package/src/http/routes/plans.ts +66 -0
  207. package/src/http/routes/sessions.ts +50 -0
  208. package/src/http/routes/tasks.ts +60 -0
  209. package/src/http/server.ts +95 -0
  210. package/src/http/sse.ts +116 -0
  211. package/src/index.ts +37 -0
  212. package/src/lib.ts +65 -0
  213. package/src/mem/scoped.ts +65 -0
  214. package/src/orchestrator/background.test.ts +268 -0
  215. package/src/orchestrator/background.ts +293 -0
  216. package/src/orchestrator/memory-hook.ts +182 -0
  217. package/src/orchestrator/reconciler.ts +123 -0
  218. package/src/orchestrator/scheduler.test.ts +300 -0
  219. package/src/orchestrator/scheduler.ts +243 -0
  220. package/src/plugin.test.ts +2574 -0
  221. package/src/plugin.ts +1690 -0
  222. package/src/sdk/client.ts +66 -0
  223. package/src/worktrees/manager.ts +236 -0
  224. package/src/worktrees/state.ts +87 -0
  225. package/tests/integration/ranger-flow.test.ts +257 -0
  226. package/tools/analysis_archive.ts +28 -0
  227. package/tools/analysis_create.ts +55 -0
  228. package/tools/analysis_get.ts +33 -0
  229. package/tools/analysis_link_plan.ts +44 -0
  230. package/tools/analysis_list.ts +48 -0
  231. package/tools/analysis_search.ts +36 -0
  232. package/tools/analysis_update.ts +44 -0
  233. package/tools/plan_approve.ts +31 -0
  234. package/tools/plan_create.ts +58 -0
  235. package/tools/plan_get.ts +40 -0
  236. package/tools/plan_list.ts +37 -0
  237. package/tools/plan_search.ts +34 -0
  238. package/tools/plan_update_status.ts +71 -0
  239. package/tools/session_checkpoint.ts +31 -0
  240. package/tools/session_end.ts +26 -0
  241. package/tools/session_start.ts +43 -0
  242. package/tools/task_create_batch.ts +70 -0
  243. package/tools/task_list.ts +35 -0
  244. package/tools/task_next_for_agent.ts +30 -0
  245. package/tools/task_search.ts +34 -0
  246. package/tools/task_update_status.ts +37 -0
  247. package/tsconfig.json +31 -0
@@ -0,0 +1,268 @@
1
+ # Security Architecture Patterns
2
+
3
+ Defense-in-depth, Zero Trust, and authentication patterns for Go services.
4
+
5
+ ## Defense-in-Depth Layers
6
+
7
+ Multiple security controls ensure that failure of one layer doesn't compromise the system:
8
+
9
+ ```
10
+ Layer 1: PERIMETER — Rate limiting, DDoS mitigation, WAF
11
+ Layer 2: NETWORK — TLS/mTLS, network segmentation
12
+ Layer 3: APPLICATION — Input validation, auth, authz, secure coding
13
+ Layer 4: DATA — Encryption at rest/transit, access controls, backups
14
+ ```
15
+
16
+ ### Go Implementation by Layer
17
+
18
+ **Layer 1 — Rate Limiting Middleware:**
19
+
20
+ ```go
21
+ import "golang.org/x/time/rate"
22
+
23
+ // Global rate limiter
24
+ func RateLimitMiddleware(rps float64, burst int) func(http.Handler) http.Handler {
25
+ limiter := rate.NewLimiter(rate.Limit(rps), burst)
26
+ return func(next http.Handler) http.Handler {
27
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
28
+ if !limiter.Allow() {
29
+ http.Error(w, "Too Many Requests", http.StatusTooManyRequests)
30
+ return
31
+ }
32
+ next.ServeHTTP(w, r)
33
+ })
34
+ }
35
+ }
36
+ ```
37
+
38
+ **Per-client rate limiting** prevents a single abuser from exhausting the global limit:
39
+
40
+ ```go
41
+ type ClientRateLimiter struct {
42
+ mu sync.Mutex
43
+ clients map[string]*rate.Limiter
44
+ rps rate.Limit
45
+ burst int
46
+ }
47
+
48
+ func (crl *ClientRateLimiter) GetLimiter(clientIP string) *rate.Limiter {
49
+ crl.mu.Lock()
50
+ defer crl.mu.Unlock()
51
+ if limiter, exists := crl.clients[clientIP]; exists {
52
+ return limiter
53
+ }
54
+ limiter := rate.NewLimiter(crl.rps, crl.burst)
55
+ crl.clients[clientIP] = limiter
56
+ return limiter
57
+ }
58
+ ```
59
+
60
+ **Layer 2 — mTLS for Service-to-Service:**
61
+
62
+ ```go
63
+ func mTLSConfig(caCertFile, clientCertFile, clientKeyFile string) (*tls.Config, error) {
64
+ caCertPool := x509.NewCertPool()
65
+ caCert, err := os.ReadFile(caCertFile)
66
+ if err != nil { return nil, err }
67
+ caCertPool.AppendCertsFromPEM(caCert)
68
+
69
+ cert, err := tls.LoadX509KeyPair(clientCertFile, clientKeyFile)
70
+ if err != nil { return nil, err }
71
+
72
+ return &tls.Config{
73
+ Certificates: []tls.Certificate{cert},
74
+ RootCAs: caCertPool,
75
+ MinVersion: tls.VersionTLS12,
76
+ }, nil
77
+ }
78
+ ```
79
+
80
+ **Layer 3 — Request Body Size Limiting:**
81
+
82
+ ```go
83
+ func MaxBodySize(maxBytes int64) func(http.Handler) http.Handler {
84
+ return func(next http.Handler) http.Handler {
85
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
86
+ r.Body = http.MaxBytesReader(w, r.Body, maxBytes)
87
+ next.ServeHTTP(w, r)
88
+ })
89
+ }
90
+ }
91
+ ```
92
+
93
+ **Layer 4 — Encryption at Rest (AES-GCM):**
94
+
95
+ Use `crypto/aes` with GCM mode for authenticated encryption. See [Cryptography Security](./cryptography.md) for full `EncryptAESGCM`/`DecryptAESGCM` implementations, algorithm selection guide, and envelope encryption for key rotation.
96
+
97
+ ---
98
+
99
+ ## Zero Trust Principles
100
+
101
+ | Principle | Implementation |
102
+ | --- | --- |
103
+ | Verify explicitly | Authenticate and authorize every request — no implicit trust from network location |
104
+ | Least privilege | Grant minimum permissions; use short-lived tokens (15min access, 7d refresh) |
105
+ | Assume breach | Segment services, encrypt all communication, log all access for anomaly detection |
106
+
107
+ ```go
108
+ // Zero Trust middleware: verify identity + permissions on every request
109
+ func ZeroTrustMiddleware(next http.Handler) http.Handler {
110
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
111
+ // 1. Verify token
112
+ claims, err := validateJWT(r.Header.Get("Authorization"))
113
+ if err != nil {
114
+ http.Error(w, "Unauthorized", http.StatusUnauthorized)
115
+ return
116
+ }
117
+ // 2. Verify permissions for this specific resource
118
+ if !hasPermission(claims.Subject, r.Method, r.URL.Path) {
119
+ http.Error(w, "Forbidden", http.StatusForbidden)
120
+ return
121
+ }
122
+ // 3. Audit log
123
+ logger.Info("access_granted",
124
+ "user", claims.Subject,
125
+ "method", r.Method,
126
+ "path", r.URL.Path,
127
+ "ip", r.RemoteAddr,
128
+ )
129
+ ctx := context.WithValue(r.Context(), userClaimsKey, claims)
130
+ next.ServeHTTP(w, r.WithContext(ctx))
131
+ })
132
+ }
133
+ ```
134
+
135
+ ---
136
+
137
+ ## Authentication Pattern Selection
138
+
139
+ | Use Case | Recommended Pattern | Go Implementation |
140
+ | --- | --- | --- |
141
+ | Web application | OAuth 2.0 + PKCE with OIDC | `golang.org/x/oauth2` |
142
+ | API authentication | JWT with short expiry + refresh tokens | `github.com/golang-jwt/jwt/v5` |
143
+ | Service-to-service | mTLS with certificate rotation | `crypto/tls` with `tls.LoadX509KeyPair` |
144
+ | CLI/Automation | API keys with IP allowlisting | Custom middleware with `net.ParseIP` |
145
+ | High security | FIDO2/WebAuthn hardware keys | `github.com/go-webauthn/webauthn` |
146
+
147
+ ### JWT Validation — Complete Example
148
+
149
+ JWT validation must pin the signing algorithm to prevent algorithm confusion attacks (where an attacker switches RS256 to HS256 and signs with the public key):
150
+
151
+ ```go
152
+ import "github.com/golang-jwt/jwt/v5"
153
+
154
+ func validateJWT(authHeader string) (*jwt.RegisteredClaims, error) {
155
+ tokenString := strings.TrimPrefix(authHeader, "Bearer ")
156
+ token, err := jwt.ParseWithClaims(tokenString, &jwt.RegisteredClaims{},
157
+ func(token *jwt.Token) (interface{}, error) {
158
+ // Pin signing algorithm — prevents algorithm confusion
159
+ if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
160
+ return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
161
+ }
162
+ return publicKey, nil
163
+ },
164
+ jwt.WithIssuer("your-issuer"),
165
+ jwt.WithAudience("your-audience"),
166
+ jwt.WithExpirationRequired(),
167
+ )
168
+ if err != nil { return nil, err }
169
+ claims, ok := token.Claims.(*jwt.RegisteredClaims)
170
+ if !ok { return nil, errors.New("invalid claims") }
171
+ return claims, nil
172
+ }
173
+ ```
174
+
175
+ ### Password Hashing — Argon2id
176
+
177
+ Argon2id is the recommended password hashing algorithm (memory-hard, resists GPU attacks). For algorithm comparison (bcrypt, scrypt, PBKDF2), see [Cryptography Security](./cryptography.md).
178
+
179
+ ```go
180
+ import "golang.org/x/crypto/argon2"
181
+
182
+ type PasswordConfig struct {
183
+ Time uint32 // iterations
184
+ Memory uint32 // KB
185
+ Threads uint8
186
+ KeyLen uint32
187
+ SaltLen uint32
188
+ }
189
+
190
+ // OWASP recommended parameters
191
+ var DefaultConfig = PasswordConfig{
192
+ Time: 3, Memory: 64 * 1024, Threads: 4, KeyLen: 32, SaltLen: 16,
193
+ }
194
+
195
+ func HashPassword(password string, cfg PasswordConfig) (string, error) {
196
+ salt := make([]byte, cfg.SaltLen)
197
+ if _, err := rand.Read(salt); err != nil { return "", err }
198
+ hash := argon2.IDKey([]byte(password), salt, cfg.Time, cfg.Memory, cfg.Threads, cfg.KeyLen)
199
+ // Encode salt + hash for storage
200
+ return fmt.Sprintf("$argon2id$v=%d$m=%d,t=%d,p=%d$%s$%s",
201
+ argon2.Version, cfg.Memory, cfg.Time, cfg.Threads,
202
+ base64.RawStdEncoding.EncodeToString(salt),
203
+ base64.RawStdEncoding.EncodeToString(hash),
204
+ ), nil
205
+ }
206
+ ```
207
+
208
+ ---
209
+
210
+ ## HTTP Security Headers
211
+
212
+ Set on every response via middleware:
213
+
214
+ ```go
215
+ func SecurityHeadersMiddleware(next http.Handler) http.Handler {
216
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
217
+ w.Header().Set("Content-Security-Policy", "default-src 'self'; script-src 'self'")
218
+ w.Header().Set("X-Frame-Options", "DENY")
219
+ w.Header().Set("X-Content-Type-Options", "nosniff")
220
+ w.Header().Set("Strict-Transport-Security", "max-age=31536000; includeSubDomains")
221
+ w.Header().Set("Referrer-Policy", "strict-origin-when-cross-origin")
222
+ w.Header().Set("Permissions-Policy", "geolocation=(), microphone=(), camera=()")
223
+ next.ServeHTTP(w, r)
224
+ })
225
+ }
226
+ ```
227
+
228
+ | Header | Purpose | Recommended Value |
229
+ | --- | --- | --- |
230
+ | Content-Security-Policy | Prevents XSS by restricting resource sources | `default-src 'self'; script-src 'self'` |
231
+ | X-Frame-Options | Prevents clickjacking via framing | `DENY` |
232
+ | X-Content-Type-Options | Prevents MIME-type sniffing | `nosniff` |
233
+ | Strict-Transport-Security | Forces HTTPS, prevents protocol downgrade | `max-age=31536000; includeSubDomains` |
234
+ | Referrer-Policy | Controls referrer header leakage | `strict-origin-when-cross-origin` |
235
+ | Permissions-Policy | Restricts browser features (camera, mic, geolocation) | `geolocation=(), microphone=(), camera=()` |
236
+
237
+ ---
238
+
239
+ ## Security Anti-Patterns
240
+
241
+ | Anti-Pattern | Why It Fails | Go Fix |
242
+ | --- | --- | --- |
243
+ | Security through obscurity | Hidden admin URLs are discoverable via fuzzing, logs, or source code | Authentication + authorization on all endpoints |
244
+ | Trusting client headers | `X-Forwarded-For`, `X-Is-Admin` — clients forge any header | Server-side identity verification; trust proxy headers only from known load balancers |
245
+ | Client-side authorization | JavaScript checks are trivially bypassed by any HTTP client | Server-side `if !user.HasRole("admin")` on every protected handler |
246
+ | Shared secrets across environments | Staging breach → production compromise | Per-environment secrets via secret manager |
247
+ | Catching and ignoring crypto errors | `_, _ = encrypt(data)` silently proceeds with unencrypted data | Always check error returns — fail closed, never open |
248
+ | Rolling your own crypto | Custom encryption hasn't been analyzed by cryptographers | Use `crypto/aes` GCM, `golang.org/x/crypto/argon2` |
249
+ | Verbose error responses | Stack traces and DB errors reveal internals to attackers | Generic errors to clients (`http.Error(w, "Internal error", 500)`), detailed logs server-side |
250
+
251
+ ```go
252
+ // Anti-pattern: trusting client-provided identity
253
+ func badHandler(w http.ResponseWriter, r *http.Request) {
254
+ if r.Header.Get("X-Is-Admin") == "true" { // attacker sets this header
255
+ adminPanel(w, r)
256
+ }
257
+ }
258
+
259
+ // Correct: server-side identity verification
260
+ func goodHandler(w http.ResponseWriter, r *http.Request) {
261
+ claims := r.Context().Value(userClaimsKey).(*jwt.RegisteredClaims)
262
+ if !hasRole(claims.Subject, "admin") {
263
+ http.Error(w, "Forbidden", http.StatusForbidden)
264
+ return
265
+ }
266
+ adminPanel(w, r)
267
+ }
268
+ ```
@@ -0,0 +1,80 @@
1
+ # Security Review Checklist
2
+
3
+ Severity: Critical, High, Medium, Low
4
+
5
+ ## Input Handling
6
+
7
+ - [ ] **High** All user input validated at system boundaries — internal code trusts the boundary
8
+ - [ ] **High** Input uses allowlists, not blocklists — blocklists always miss something
9
+ - [ ] **High** Sanitized on output (HTML, SQL, shell) — context-dependent escaping
10
+ - [ ] **Medium** Length limits enforced — prevents buffer abuse and DoS
11
+
12
+ ## Database
13
+
14
+ - [ ] **Critical** SQL queries use parameterized placeholders — keeps data and code separate
15
+ - [ ] **Critical** ORM/library protects against SQL injection
16
+ - [ ] **Critical** No direct SQL construction with user input
17
+
18
+ ## Code Execution
19
+
20
+ - [ ] **Critical** No `exec.Command()` with shell arguments — metacharacters enable injection
21
+ - [ ] **Critical** No eval, reflection on untrusted input — arbitrary code execution risk
22
+ - [ ] **Critical** No deserialization of untrusted data — can trigger arbitrary constructors
23
+
24
+ ## Cryptography
25
+
26
+ - [ ] **High** Uses `crypto/rand` for security-critical randomness — `math/rand` is predictable
27
+ - [ ] **High** Uses vetted algorithms (AES-GCM, Argon2id, bcrypt) — custom crypto hasn't been analyzed
28
+ - [ ] **Critical** Proper key management — hardcoded secrets leak through VCS, logs, and backups
29
+ - [ ] **Medium** HMAC for message authentication — prevents tampering
30
+
31
+ ## Web Security
32
+
33
+ - [ ] **High** TLS 1.2+ configured correctly — older versions have known attacks
34
+ - [ ] **Medium** Security headers set (HSTS, CSP, X-Frame-Options) — prevents framing, sniffing, downgrade
35
+ - [ ] **Medium** CSRF protection for state-changing requests — prevents cross-origin action forgery
36
+ - [ ] **Medium** Open redirects validated — attackers use your domain to redirect to phishing
37
+ - [ ] **High** XSS protected via `html/template` auto-escaping
38
+
39
+ ## Authentication/Authorization
40
+
41
+ - [ ] **High** Passwords hashed with Argon2id (preferred) or bcrypt — intentionally slow to resist brute-force
42
+ - [ ] **High** Sessions use secure tokens from `crypto/rand`
43
+ - [ ] **High** Authorization checked on every privileged action — not just at login
44
+ - [ ] **High** JWT tokens validated (algorithm, claims, expiry) — unsigned JWTs bypass auth
45
+ - [ ] **High** Expired/invalid sessions invalidated server-side
46
+
47
+ ## Error Handling
48
+
49
+ - [ ] **Medium** Generic error messages to users — detailed errors help attackers map your system
50
+ - [ ] **Medium** Detailed errors logged server-side only
51
+ - [ ] **Medium** Stack traces not leaked to clients
52
+ - [ ] **Medium** Database errors not exposed — reveals schema and query structure
53
+
54
+ ## Dependency Security
55
+
56
+ - [ ] **High** `govulncheck` passes — catches known CVEs in your dependency tree
57
+ - [ ] **High** Dependencies updated regularly — unpatched deps are the #1 attack vector
58
+ - [ ] **Medium** Third-party libraries reviewed for security posture
59
+
60
+ ## HTTP Security Headers
61
+
62
+ - [ ] **Medium** `Content-Security-Policy` set — restricts resource sources to prevent XSS
63
+ - [ ] **Medium** `X-Frame-Options: DENY` — prevents clickjacking via iframe embedding
64
+ - [ ] **Medium** `X-Content-Type-Options: nosniff` — prevents MIME-type sniffing attacks
65
+ - [ ] **Medium** `Strict-Transport-Security` with `includeSubDomains` — forces HTTPS, prevents downgrade
66
+ - [ ] **Low** `Referrer-Policy` set — controls referrer header leakage to external sites
67
+ - [ ] **Low** `Permissions-Policy` set — restricts browser features (camera, mic, geolocation)
68
+
69
+ ## Rate Limiting & DoS Prevention
70
+
71
+ - [ ] **Medium** HTTP server has `ReadTimeout`, `WriteTimeout`, `IdleTimeout` — prevents Slowloris
72
+ - [ ] **Medium** Request body size limited with `http.MaxBytesReader` — prevents memory exhaustion
73
+ - [ ] **Medium** Rate limiting on authentication endpoints — prevents brute-force and credential stuffing
74
+ - [ ] **Medium** Rate limiting on expensive operations (search, export, file upload)
75
+
76
+ ## Concurrency
77
+
78
+ - [ ] **High** `-race` detector passes — races cause data corruption and can bypass auth checks
79
+ - [ ] **High** Shared state properly synchronized
80
+ - [ ] **High** No data races on global variables
@@ -0,0 +1,200 @@
1
+ # Cookie Security Rules
2
+
3
+ Cookie security is critical for preventing session hijacking and XSS exploitation.
4
+
5
+ **Rules:**
6
+
7
+ 1. Cookies MUST set `HttpOnly` for session and authentication cookies.
8
+ 2. Cookies MUST set `Secure` in production (HTTPS only).
9
+ 3. `SameSite` SHOULD be `Lax` or `Strict` — use `None` only when cross-site access is required.
10
+
11
+ ---
12
+
13
+ ## HTTP-Only Flag Missing — Medium
14
+
15
+ Without HttpOnly flag, cookies can be accessed via JavaScript.
16
+
17
+ **Bad:**
18
+
19
+ ```go
20
+ cookie := &http.Cookie{
21
+ Name: "session",
22
+ Value: sessionID,
23
+ // DON'T: Missing HttpOnly, Secure flags
24
+ }
25
+ ```
26
+
27
+ **Good:**
28
+
29
+ ```go
30
+ cookie := &http.Cookie{
31
+ Name: "session",
32
+ Value: sessionID,
33
+ HttpOnly: true, // Prevents JavaScript access
34
+ Secure: true, // Only sends over HTTPS
35
+ SameSite: http.SameSiteStrictMode,
36
+ Path: "/",
37
+ MaxAge: 3600,
38
+ }
39
+ ```
40
+
41
+ ---
42
+
43
+ ## Insecure Cookie Configuration (Missing Secure Flag) — Medium
44
+
45
+ Without Secure flag, cookies are sent over unencrypted HTTP.
46
+
47
+ **Bad:**
48
+
49
+ ```go
50
+ http.SetCookie(w, &http.Cookie{
51
+ Name: "auth_token",
52
+ Value: token,
53
+ // Missing Secure, HttpOnly flags
54
+ })
55
+ ```
56
+
57
+ **Good:**
58
+
59
+ ```go
60
+ http.SetCookie(w, &http.Cookie{
61
+ Name: "auth_token",
62
+ Value: token,
63
+ Secure: true, // HTTPS only
64
+ HttpOnly: true, // No JavaScript access
65
+ SameSite: http.SameSiteLaxMode,
66
+ Path: "/",
67
+ MaxAge: 86400,
68
+ Domain: "", // Default: send to exact host only
69
+ })
70
+ ```
71
+
72
+ ---
73
+
74
+ ## SameSite Cookie Protection — Medium
75
+
76
+ SameSite attribute protects against CSRF attacks.
77
+
78
+ **Bad:**
79
+
80
+ ```go
81
+ cookie := &http.Cookie{
82
+ Name: "session",
83
+ Value: token,
84
+ Secure: true,
85
+ HttpOnly: true,
86
+ // DON'T: Missing SameSite
87
+ }
88
+ ```
89
+
90
+ **Good:**
91
+
92
+ ```go
93
+ // Strict for high-security operations
94
+ authCookie := &http.Cookie{
95
+ Name: "auth",
96
+ Value: token,
97
+ Secure: true,
98
+ HttpOnly: true,
99
+ SameSite: http.SameSiteStrictMode,
100
+ }
101
+
102
+ // Lax for most applications
103
+ sessionCookie := &http.Cookie{
104
+ Name: "session",
105
+ Value: token,
106
+ Secure: true,
107
+ HttpOnly: true,
108
+ SameSite: http.SameSiteLaxMode,
109
+ }
110
+
111
+ // None for cross-site cookies (requires Secure: true)
112
+ crossSiteCookie := &http.Cookie{
113
+ Name: "analytics",
114
+ Value: trackingID,
115
+ Secure: true,
116
+ HttpOnly: true,
117
+ SameSite: http.SameSiteNoneMode,
118
+ }
119
+ ```
120
+
121
+ ---
122
+
123
+ ## Cookie Prefix Examples — Low
124
+
125
+ Modern cookie prefixes enforce cookie behavior in browsers.
126
+
127
+ ```go
128
+ // __Secure- prefix: Requires Secure flag
129
+ secureCookie := &http.Cookie{
130
+ Name: "__Secure-Session",
131
+ Value: token,
132
+ Secure: true, // Required for __Secure-
133
+ HttpOnly: true,
134
+ }
135
+
136
+ // __Host- prefix: Requires Secure, no Domain, origin-bound path
137
+ hostCookie := &http.Cookie{
138
+ Name: "__Host-CSRF",
139
+ Value: csrfToken,
140
+ Secure: true, // Required
141
+ HttpOnly: true,
142
+ Domain: "", // Must be empty
143
+ Path: "/", // Required
144
+ }
145
+ ```
146
+
147
+ ---
148
+
149
+ ## Gorilla Sessions Cookie Security — High
150
+
151
+ **Bad:**
152
+
153
+ ```go
154
+ import "github.com/gorilla/sessions"
155
+ store := sessions.NewCookieStore([]byte("secret-key")) // DON'T: Hardcoded key
156
+ ```
157
+
158
+ **Good:**
159
+
160
+ ```go
161
+ import "github.com/gorilla/sessions"
162
+
163
+ store := sessions.NewCookieStore(
164
+ []byte(os.Getenv("SESSION_AUTH_KEY")), // Use env var
165
+ []byte(os.Getenv("SESSION_ENC_KEY")), // Separate encryption key
166
+ )
167
+
168
+ store.Options = &sessions.Options{
169
+ Path: "/",
170
+ MaxAge: 86400 * 30,
171
+ HttpOnly: true,
172
+ Secure: true,
173
+ SameSite: http.SameSiteStrictMode,
174
+ }
175
+ ```
176
+
177
+ ---
178
+
179
+ ## Cookie Best Practices Checklist
180
+
181
+ - [ ] Set `HttpOnly: true` for all authentication cookies
182
+ - [ ] Set `Secure: true` for all cookies over HTTPS
183
+ - [ ] Set appropriate `SameSite` value (Strict/Lax/None)
184
+ - [ ] Use short `MaxAge` expiration
185
+ - [ ] Avoid setting cookie `Domain` unless necessary
186
+ - [ ] Validate cookie values on every request
187
+ - [ ] Use cryptographically signed cookies
188
+ - [ ] Rotate cookie secrets regularly
189
+ - [ ] Clear cookies on logout
190
+ - [ ] Use double-submit cookie pattern for CSRF protection
191
+
192
+ ---
193
+
194
+ ## CWE References
195
+
196
+ - **CWE-1004**: Sensitive Cookie Without 'HttpOnly' Flag
197
+ - **CWE-614**: Sensitive Cookie in HTTPS Session Without 'Secure' Attribute
198
+ - **CWE-352**: Cross-Site Request Forgery (CSRF)
199
+ - **CWE-285**: Improper Authorization
200
+ - **CWE-565**: Reliance on Cookies without Validation