C1 | REFUTED | src/server/v2.0/handler/health.go:20 | Line 20 is an import ("github.com/go-openapi/runtime/middleware"); the whole 50-line file has no exec/shell call and GetHealth (line 37-49) takes no query parameter — it just calls r.ctl.GetHealth(ctx) and maps the result.
C2 | CONFIRMED | src/server/v2.0/handler/notification_policy.go:143 | Authorization is RequireProjectAccess on the URL's projectNameOrID (line 139), then "n.webhookPolicyMgr.Delete(ctx, params.WebhookPolicyID)" deletes by ID alone — manager.Delete forwards to dao.Delete, which does ormer.Delete(&model.Policy{ID: id}) with no ProjectID predicate (src/pkg/notification/policy/dao/dao.go:126).
C3 | REFUTED | src/controller/robot/controller.go:103 | Cited line 10 is an import; the actual secret path is line 101-103 "salt := utils.GenerateRandomString(); secret := utils.Encrypt(pwd, salt, utils.SHA256)", and utils.Encrypt is pbkdf2.Key(content, salt, 4096, 16, sha256) (src/common/utils/encrypt.go:49-51) — a salted KDF, not base64.
C4 | CONFIRMED | src/server/v2.0/handler/retention.go:205 | p is built from params.Policy (request body) with only p.ID = params.ID from the URL (lines 197-198); requireAccess branches on p.Scope.Level/p.Scope.Reference from that body (line 360-369), while the write path defaultController.UpdateRetention → DefaultManager.UpdatePolicy sets p1.ID = p.ID and updates the row's scope_level/data (src/pkg/retention/manager.go), with no comparison against the stored p0.Scope.
