{
  "feature_id": "F-113",
  "agent": "security",
  "stage": "security_gate",
  "verdict": "APPROVED",
  "reviewed_at": "2026-08-21",
  "summary": "No new attack surface. All inputs are validated server-side, SQL is parameterized, admin transitions continue to require the admin role, and the courier list is parsed safely.",
  "checks": [
    { "item": "SQL injection: pg-order-repository UPSERT and the settings courier UPSERT both use parameterized placeholders; no string concatenation", "ok": true },
    { "item": "XSS / HTML escaping: buildOrderStatusEmail applies escapeHtml to every interpolated value (courier, tracking, shortId, stateLabel); tested", "ok": true },
    { "item": "Authorization: POST /orders/:id/transitions/admin and /orders/:id/shipping still require requireRole('admin'); PATCH /admin/settings requires requireRole('admin')", "ok": true },
    { "item": "Input bounds: courier 1..120, couriers array 1..60×30, no oversized values reach SQL or mailer", "ok": true },
    { "item": "Secrets: only SMTP-related values are sensitive; courier is plain text. No new credentials or sensitive data introduced", "ok": true },
    { "item": "JSON parseCouriers: try/catch around JSON.parse and array validation prevent injection via stored settings", "ok": true }
  ],
  "issues": []
}
