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,315 @@
1
+ # Injection Security Rules
2
+
3
+ Injection vulnerabilities allow attackers to execute arbitrary code, queries, or commands.
4
+
5
+ **Rules:**
6
+
7
+ 1. SQL queries MUST use parameterized placeholders — NEVER concatenate user input.
8
+ 2. Command execution MUST use `exec.Command` with separate args — NEVER shell interpolation.
9
+ 3. HTML output MUST use `html/template` for automatic escaping.
10
+ 4. SSRF: outbound URLs MUST be validated against an allowlist.
11
+
12
+ ---
13
+
14
+ ## SQL Injection — Critical
15
+
16
+ Building SQL queries by concatenating user input. Always use prepared statements with placeholders.
17
+
18
+ **Bad:**
19
+
20
+ ```go
21
+ query := fmt.Sprintf("SELECT * FROM users WHERE name = '%s'", input)
22
+ query := "SELECT * FROM users WHERE id = " + id
23
+ query := "DELETE FROM orders WHERE id = " + strconv.Itoa(orderID) // safe but inconsistent — use placeholders everywhere
24
+ ```
25
+
26
+ **Good:**
27
+
28
+ ```go
29
+ // Placeholder syntax varies by driver: $1 (pgx/lib/pq), ? (MySQL/SQLite)
30
+ db.QueryRow("SELECT * FROM users WHERE name = $1", input)
31
+ db.Exec("DELETE FROM orders WHERE id = $1", orderID)
32
+ ```
33
+
34
+ ### Dynamic IN clauses
35
+
36
+ Never build `IN (...)` by joining user strings. Generate numbered placeholders.
37
+
38
+ **Bad:**
39
+
40
+ ```go
41
+ query := fmt.Sprintf("SELECT * FROM users WHERE id IN (%s)", strings.Join(ids, ","))
42
+ ```
43
+
44
+ **Good:**
45
+
46
+ ```go
47
+ // Build placeholders: $1, $2, $3, ...
48
+ placeholders := make([]string, len(ids))
49
+ args := make([]any, len(ids))
50
+ for i, id := range ids {
51
+ placeholders[i] = fmt.Sprintf("$%d", i+1)
52
+ args[i] = id
53
+ }
54
+ query := fmt.Sprintf("SELECT * FROM users WHERE id IN (%s)", strings.Join(placeholders, ","))
55
+ rows, err := db.Query(query, args...)
56
+ ```
57
+
58
+ With `sqlx`:
59
+
60
+ ```go
61
+ query, args, err := sqlx.In("SELECT * FROM users WHERE id IN (?)", ids)
62
+ query = db.Rebind(query) // converts ? to $1,$2,... for postgres
63
+ rows, err := db.Query(query, args...)
64
+ ```
65
+
66
+ ### Dynamic column names and ORDER BY
67
+
68
+ Placeholders only work for **values**, not identifiers (table/column names) or SQL keywords. Allowlist identifiers explicitly.
69
+
70
+ **Bad:**
71
+
72
+ ```go
73
+ query := fmt.Sprintf("SELECT * FROM users ORDER BY %s", sortCol) // SQL injection
74
+ ```
75
+
76
+ **Good:**
77
+
78
+ ```go
79
+ allowed := map[string]string{
80
+ "name": "name", "created": "created_at", "email": "email",
81
+ }
82
+ col, ok := allowed[sortCol]
83
+ if !ok {
84
+ col = "created_at"
85
+ }
86
+ query := fmt.Sprintf("SELECT * FROM users ORDER BY %s", col) // safe: col is from allowlist
87
+ ```
88
+
89
+ ### Dynamic WHERE filters
90
+
91
+ Build queries incrementally; parameterize every user-supplied value.
92
+
93
+ ```go
94
+ var conditions []string
95
+ var args []any
96
+ idx := 1
97
+
98
+ if name != "" {
99
+ conditions = append(conditions, fmt.Sprintf("name = $%d", idx))
100
+ args = append(args, name)
101
+ idx++
102
+ }
103
+ if minAge > 0 {
104
+ conditions = append(conditions, fmt.Sprintf("age >= $%d", idx))
105
+ args = append(args, minAge)
106
+ idx++
107
+ }
108
+
109
+ query := "SELECT * FROM users"
110
+ if len(conditions) > 0 {
111
+ query += " WHERE " + strings.Join(conditions, " AND ")
112
+ }
113
+ rows, err := db.Query(query, args...)
114
+ ```
115
+
116
+ ### Prefer `sqlx` or `pgx` over raw `database/sql`
117
+
118
+ Libraries like `sqlx` and `pgx` provide safer ergonomics (named parameters, `IN` clause expansion, struct scanning) while still using prepared statements under the hood. They reduce the temptation to fall back to string concatenation for complex queries.
119
+
120
+ ---
121
+
122
+ ## XPath Injection — High
123
+
124
+ XPath injection allows manipulation of XML data queries.
125
+
126
+ **Bad:**
127
+
128
+ ```go
129
+ xpathQuery := "//user[@username='" + username + "']" // Vulnerable
130
+ ```
131
+
132
+ **Good:**
133
+
134
+ ```go
135
+ // Use numeric ID
136
+ xpathQuery := fmt.Sprintf("//user[@id='%d']", userID)
137
+
138
+ // Or parse XML without XPath
139
+ ```
140
+
141
+ ---
142
+
143
+ ## Code Injection — Critical
144
+
145
+ Generating code from unvalidated user input.
146
+
147
+ **Bad:**
148
+
149
+ ```go
150
+ template := "func handle" + resourceName + "() {...}" // DON'T
151
+ ```
152
+
153
+ **Good:**
154
+
155
+ ```go
156
+ // Validate resource name matches whitelist
157
+ if !allowedResources[resourceName] {
158
+ return errors.New("invalid resource")
159
+ }
160
+ // Use predefined templates
161
+ ```
162
+
163
+ ---
164
+
165
+ ## Command Injection — Critical
166
+
167
+ Passing unvalidated input to shell commands.
168
+
169
+ **Bad:**
170
+
171
+ ```go
172
+ cmd := exec.Command("sh", "-c", "rm -f /tmp/"+filename) // DON'T
173
+ ```
174
+
175
+ **Good:**
176
+
177
+ ```go
178
+ cmd := exec.Command("rm", "-f", filepath.Join("/tmp", filename))
179
+
180
+ // Better: validate filename
181
+ if filepath.Base(filename) != filename {
182
+ return errors.New("invalid filename")
183
+ }
184
+ ```
185
+
186
+ ---
187
+
188
+ ## Template Injection — High
189
+
190
+ Using untrusted input in templates.
191
+
192
+ **Bad:**
193
+
194
+ ```go
195
+ data := r.URL.Query().Get("user") // Untrusted input
196
+ t.Execute(w, data)
197
+ ```
198
+
199
+ **Good:**
200
+
201
+ ```go
202
+ // Validate input
203
+ user := strings.TrimSpace(r.URL.Query().Get("user"))
204
+ if !allowedRoles[role] {
205
+ role = "user"
206
+ }
207
+ t.Execute(w, data)
208
+ ```
209
+
210
+ ---
211
+
212
+ ## Cross-Site Scripting (XSS) — High
213
+
214
+ XSS allows attackers to execute malicious scripts.
215
+
216
+ **Bad:**
217
+
218
+ ```go
219
+ w.Write([]byte(fmt.Sprintf("<div>%s</div>", data))) // DON'T
220
+ ```
221
+
222
+ **Good:**
223
+
224
+ ```go
225
+ import "html/template"
226
+ t := template.Must(template.New("safe").Parse("<div>{{.}}</div>"))
227
+ t.Execute(w, data) // Auto-escapes
228
+ ```
229
+
230
+ ---
231
+
232
+ ## HTML Tag Injection — High
233
+
234
+ Injecting HTML tags through unvalidated input.
235
+
236
+ **Bad:**
237
+
238
+ ```go
239
+ fmt.Fprintf(w, "<div>Welcome, %s!</div>", input) // DON'T
240
+ ```
241
+
242
+ **Good:**
243
+
244
+ ```go
245
+ import "html"
246
+ escaped := html.EscapeString(input)
247
+ fmt.Fprintf(w, "<div>Welcome, %s!</div>", escaped)
248
+ ```
249
+
250
+ ---
251
+
252
+ ## Server-Side Request Forgery (SSRF) — High
253
+
254
+ Forcing the server to make requests to unintended endpoints.
255
+
256
+ **Bad:**
257
+
258
+ ```go
259
+ url := r.URL.Query().Get("url")
260
+ resp, _ := http.Get(url) // DON'T: No validation
261
+ ```
262
+
263
+ **Good:**
264
+
265
+ ```go
266
+ u, err := url.Parse(targetURL)
267
+ // Block non-HTTP/S protocols
268
+ if u.Scheme != "http" && u.Scheme != "https" {
269
+ return errors.New("invalid scheme")
270
+ }
271
+ // Block internal hosts
272
+ if isInternalIP(u.Hostname()) {
273
+ return errors.New("internal host not allowed")
274
+ }
275
+ // Block metadata endpoints
276
+ if strings.Contains(u.Hostname(), "metadata.") {
277
+ return errors.New("metadata endpoint blocked")
278
+ }
279
+ ```
280
+
281
+ ---
282
+
283
+ ## Unsafe Deserialization — Critical
284
+
285
+ Deserializing untrusted input can lead to resource exhaustion, type confusion, or unsafe object construction.
286
+
287
+ **Bad:**
288
+
289
+ ```go
290
+ dec := gob.NewDecoder(r.Body) // DON'T: gob is not hardened for adversarial input
291
+ var user interface{}
292
+ dec.Decode(&user)
293
+ ```
294
+
295
+ **Good:**
296
+
297
+ ```go
298
+ import "encoding/json"
299
+ dec := json.NewDecoder(r.Body)
300
+ var user User
301
+ dec.Decode(&user) // JSON doesn't execute code
302
+ // Validate fields
303
+ ```
304
+
305
+ ---
306
+
307
+ ## CWE References
308
+
309
+ - **CWE-78**: OS Command Injection
310
+ - **CWE-89**: SQL Injection
311
+ - **CWE-94**: Code Injection
312
+ - **CWE-79**: Cross-site Scripting (XSS)
313
+ - **CWE-918**: Server-Side Request Forgery (SSRF)
314
+ - **CWE-502**: Deserialization of Untrusted Data
315
+ - **CWE-20**: Improper Input Validation
@@ -0,0 +1,163 @@
1
+ # Logging Security Rules
2
+
3
+ Logging sensitive information can lead to data exposure and compliance violations.
4
+
5
+ **Rules:**
6
+
7
+ 1. PII MUST NEVER be logged — filter passwords, tokens, emails, and personal data.
8
+ 2. Log injection MUST be prevented — sanitize user input before logging.
9
+ 3. Error messages MUST NOT expose internals to users — log details server-side, return generic messages.
10
+
11
+ ---
12
+
13
+ ## Sensitive Data in Logs — Medium
14
+
15
+ **Bad:**
16
+
17
+ ```go
18
+ type User struct {
19
+ ID string
20
+ Username string
21
+ Password string
22
+ Token string
23
+ }
24
+
25
+ func logUserLogin(user *User) {
26
+ log.Printf("User logged in: %+v\n", user) // DON'T: Logs password, token
27
+ }
28
+ ```
29
+
30
+ **Good:**
31
+
32
+ ```go
33
+ import "log/slog"
34
+
35
+ func logUserLogin(logger *slog.Logger, user *User) {
36
+ logger.Info("user_login",
37
+ "user_id", user.ID,
38
+ "username", user.Username,
39
+ // Don't log: password, token
40
+ )
41
+ }
42
+ ```
43
+
44
+ ---
45
+
46
+ ## Log Injection — Low
47
+
48
+ User input in logs can lead to log injection attacks.
49
+
50
+ **Bad:**
51
+
52
+ ```go
53
+ log.Printf("User logged in: %s\n", username) // DON'T: No sanitization
54
+ ```
55
+
56
+ **Good:**
57
+
58
+ ```go
59
+ import "log/slog"
60
+
61
+ // Sanitize user input before logging
62
+ func sanitizeLogInput(input string) string {
63
+ // Remove control characters
64
+ var result strings.Builder
65
+ for _, r := range input {
66
+ if !unicode.IsControl(r) || r == '\n' || r == '\t' {
67
+ result.WriteRune(r)
68
+ }
69
+ }
70
+ return result.String()
71
+ }
72
+
73
+ func logUsername(logger *slog.Logger, username string) {
74
+ sanitized := sanitizeLogInput(username)
75
+ logger.Info("user_login", "username", sanitized)
76
+ }
77
+ ```
78
+
79
+ ---
80
+
81
+ ## Information Leakage in Error Messages — Medium
82
+
83
+ **Bad:**
84
+
85
+ ```go
86
+ func handleDatabaseError(err error) error {
87
+ return fmt.Errorf("database error: %v", err) // DON'T: Leaks internal details
88
+ }
89
+
90
+ func dbErrorToHTTP(err error) {
91
+ http.Error(w, "Error: "+err.Error(), 500) // DON'T
92
+ }
93
+ ```
94
+
95
+ **Good:**
96
+
97
+ ```go
98
+ func handleDatabaseError(logger *slog.Logger, err error) error {
99
+ // Log detailed error for debugging
100
+ logger.Error("database_error", "error", err.Error())
101
+ // Return generic message to client
102
+ return errors.New("database operation failed")
103
+ }
104
+
105
+ func dbErrorToHTTP(w http.ResponseWriter, logger *slog.Logger, err error) {
106
+ logger.Error("database_error", "error", err.Error())
107
+ http.Error(w, "Internal server error", http.StatusInternalServerError)
108
+ }
109
+ ```
110
+
111
+ ---
112
+
113
+ ## General Logger Security — Low
114
+
115
+ **Bad:**
116
+
117
+ ```go
118
+ import "log"
119
+ log.Println("User logged in:", user.ID, password) // DON'T: Logs password
120
+ fmt.Printf("DEBUG: %+v\n", data) // DON'T: Raw data
121
+ ```
122
+
123
+ **Good:**
124
+
125
+ ```go
126
+ import "log/slog"
127
+
128
+ handler := slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
129
+ Level: slog.LevelInfo,
130
+ AddSource: false,
131
+ })
132
+ logger := slog.New(handler)
133
+
134
+ logger.Info("user_login",
135
+ "user_id", userID,
136
+ "ip_address", request.RemoteIP,
137
+ )
138
+ ```
139
+
140
+ ---
141
+
142
+ ## Log Security Checklist
143
+
144
+ - [ ] No passwords, tokens, or secrets in logs
145
+ - [ ] No PII/PHI in production logs
146
+ - [ ] Sanitize user input before logging
147
+ - [ ] Use structured logging (JSON)
148
+ - [ ] Implement log level strategy
149
+ - [ ] Separate access logs from error logs
150
+ - [ ] Log file permissions restricted (e.g., 600)
151
+ - [ ] Log rotation prevents disk exhaustion
152
+ - [ ] Generic error messages to clients
153
+ - [ ] Detailed errors only in internal logs
154
+
155
+ ---
156
+
157
+ ## CWE References
158
+
159
+ - **CWE-532**: Insertion of Sensitive Information into Log File
160
+ - **CWE-117**: Improper Output Neutralization for Logs
161
+ - **CWE-209**: Information Exposure Through an Error Message
162
+ - **CWE-200**: Exposure of Sensitive Information
163
+ - **CWE-312**: Cleartext Storage of Sensitive Information
@@ -0,0 +1,241 @@
1
+ # Memory Safety Security Rules
2
+
3
+ Memory safety vulnerabilities can lead to crashes, data corruption, and security compromises.
4
+
5
+ **Rules:**
6
+
7
+ 1. Integer overflow MUST be checked at boundaries — NEVER trust unchecked arithmetic on external input.
8
+ 2. `unsafe` MUST NOT be used in application code — restrict to low-level libraries with thorough review.
9
+ 3. Data races MUST be detected with `-race` flag in CI.
10
+
11
+ ---
12
+
13
+ ## Integer Overflow — High
14
+
15
+ Integer overflows can cause unexpected behavior and crashes.
16
+
17
+ **Bad:**
18
+
19
+ ```go
20
+ func allocateBuffer(rows, cols int) []byte {
21
+ size := rows * cols // DON'T: Can overflow
22
+ return make([]byte, size)
23
+ }
24
+ ```
25
+
26
+ **Good:**
27
+
28
+ ```go
29
+ import "math"
30
+
31
+ func safeMultiply(a, b int) (int, error) {
32
+ if a == 0 || b == 0 {
33
+ return 0, nil
34
+ }
35
+ if a > math.MaxInt/b {
36
+ return 0, errors.New("integer overflow")
37
+ }
38
+ result := a * b
39
+ if result/b != a {
40
+ return 0, errors.New("overflow detected")
41
+ }
42
+ return result, nil
43
+ }
44
+
45
+ func allocateBuffer(rows, cols int) ([]byte, error) {
46
+ size, err := safeMultiply(rows, cols)
47
+ if err != nil {
48
+ return nil, err
49
+ }
50
+ const maxBufferSize = 100 * 1024 * 1024 // 100MB limit
51
+ if size > maxBufferSize {
52
+ return nil, errors.New("buffer size exceeds limit")
53
+ }
54
+ return make([]byte, size), nil
55
+ }
56
+ ```
57
+
58
+ ---
59
+
60
+ ## math/big.Rat Issues — Low
61
+
62
+ Rat can consume large amounts of memory if denominators grow without bounds.
63
+
64
+ **Bad:**
65
+
66
+ ```go
67
+ import "math/big"
68
+
69
+ func unsafeFraction(operations int) *big.Rat {
70
+ r := big.NewRat(1, 1)
71
+ for i := 0; i < operations; i++ {
72
+ r.Mul(r, big.NewRat(int64(i+1), int64(i+2))) // DON'T
73
+ }
74
+ return r // Could be memory intensive
75
+ }
76
+ ```
77
+
78
+ **Good:**
79
+
80
+ ```go
81
+ const maxRatNumBits = 1000
82
+
83
+ func safeFraction(operations int) (*big.Rat, error) {
84
+ r := big.NewRat(1, 1)
85
+ for i := 0; i < operations; i++ {
86
+ r.Mul(r, big.NewRat(int64(i+1), int64(i+2)))
87
+ if r.Num().BitLen() > maxRatNumBits || r.Denom().BitLen() > maxRatNumBits {
88
+ return nil, errors.New("fraction precision too large")
89
+ }
90
+ }
91
+ return r, nil
92
+ }
93
+ ```
94
+
95
+ ---
96
+
97
+ ## Memory Aliasing Vulnerability — Medium
98
+
99
+ Memory aliasing can cause data corruption and race conditions.
100
+
101
+ **Bad:**
102
+
103
+ ```go
104
+ func reverseBytes(data []byte) {
105
+ for i, j := 0, len(data)-1; i < j; i, j = i+1, j-1 {
106
+ data[i], data[j] = data[j], data[i] // DON'T if slices alias
107
+ }
108
+ }
109
+ ```
110
+
111
+ **Good:**
112
+
113
+ ```go
114
+ import "unsafe"
115
+
116
+ func checkOverlap(a, b []byte) bool {
117
+ if len(a) == 0 || len(b) == 0 {
118
+ return false
119
+ }
120
+ aStart := uintptr(unsafe.Pointer(&a[0]))
121
+ aEnd := aStart + uintptr(len(a))
122
+ bStart := uintptr(unsafe.Pointer(&b[0]))
123
+ bEnd := bStart + uintptr(len(b))
124
+ return aStart < bEnd && bStart < aEnd
125
+ }
126
+
127
+ func safeCopy(dest, src []byte) {
128
+ if checkOverlap(dest, src) {
129
+ temp := make([]byte, len(src))
130
+ copy(temp, src)
131
+ copy(dest, temp)
132
+ } else {
133
+ copy(dest, src)
134
+ }
135
+ }
136
+ ```
137
+
138
+ ---
139
+
140
+ ## Use of unsafe Package — High
141
+
142
+ The unsafe package bypasses Go's type safety and memory safety.
143
+
144
+ **Bad:**
145
+
146
+ ```go
147
+ import "unsafe"
148
+
149
+ func UnsafeStringToBytes(s string) []byte {
150
+ return (*[0x7fffffff]byte)(unsafe.Pointer(
151
+ (*reflect.StringHeader)(unsafe.Pointer(&s)).Data,
152
+ ))[:len(s):len(s)] // DON'T: memory corruption risk
153
+ }
154
+
155
+ func TypePun(value uint64) float64 {
156
+ return *(*float64)(unsafe.Pointer(&value)) // DON'T
157
+ }
158
+ ```
159
+
160
+ **Good:**
161
+
162
+ ```go
163
+ // Safe string encoding
164
+ func StringToBytes(s string) []byte {
165
+ return []byte(s)
166
+ }
167
+ func BytesToString(b []byte) string {
168
+ return string(b)
169
+ }
170
+
171
+ // Safe type conversion
172
+ import "encoding/binary"
173
+ func Uint64ToFloat64(value uint64) float64 {
174
+ buf := make([]byte, 8)
175
+ binary.LittleEndian.PutUint64(buf, value)
176
+ bits := binary.LittleEndian.Uint64(buf)
177
+ return math.Float64frombits(bits)
178
+ }
179
+ ```
180
+
181
+ ---
182
+
183
+ ## Data Races — High
184
+
185
+ Go's race detector is your primary defense.
186
+
187
+ **Bad:**
188
+
189
+ ```go
190
+ type Counter struct {
191
+ value int
192
+ }
193
+
194
+ func (c *Counter) Increment() {
195
+ c.value++ // DON'T: Data race without sync
196
+ }
197
+ ```
198
+
199
+ **Good:**
200
+
201
+ ```go
202
+ import "sync"
203
+
204
+ type Counter struct {
205
+ value int
206
+ mu sync.Mutex
207
+ }
208
+
209
+ func (c *Counter) Increment() {
210
+ c.mu.Lock()
211
+ defer c.mu.Unlock()
212
+ c.value++
213
+ }
214
+
215
+ // Or atomic for simple cases
216
+ import "sync/atomic"
217
+ type AtomicCounter struct {
218
+ value int64
219
+ }
220
+ func (c *AtomicCounter) Increment() {
221
+ atomic.AddInt64(&c.value, 1)
222
+ }
223
+ ```
224
+
225
+ ## Always Run Race Detector
226
+
227
+ ```bash
228
+ go test -race ./...
229
+ go build -race
230
+ ```
231
+
232
+ ---
233
+
234
+ ## CWE References
235
+
236
+ - **CWE-190**: Integer Overflow or Wraparound
237
+ - **CWE-119**: Improper Restriction of Operations within Bounds
238
+ - **CWE-125**: Out-of-bounds Read
239
+ - **CWE-787**: Out-of-bounds Write
240
+ - **CWE-362**: Race Condition
241
+ - **CWE-367**: Time-of-check Time-of-use (TOCTOU)