Appearance
SEC-48 handoff (AW / DevStop / rn-app / infra)
Work that cannot be completed inside this repository. Chat API fixes for SEC-72 object-authz and JWT verify live in @aw-chat/server and are covered by unit tests. Everything below is owned by AW platform, rn-app, or infra.
Proven here vs needs live retest
| Item | Proven in this repo | Needs AW action |
|---|---|---|
IDOR DELETE /api/devices/:id | Yes — ownership + 404 on foreign/missing; A/B test in app.test.ts | Deploy this build; live A/B on target host |
IDOR POST /api/csat (and complaints chatId) | Yes — foreign/unverifiable id → 403, no row | Deploy; live A/B |
JWT aud / iss / exp verify | Yes when JWT_AUD / JWT_ISS / REQUIRE_JWT_EXP set; prod boot requires them | Mint must emit matching claims; set env on chat host |
| JWT mint (awp-api) | N/A | Implement claims + draft policy |
| Secret rotation after exposure | N/A | Rotate shared HS256 secret; confirm |
| SEC-76 rn-app session race / logout / URL | SDK exposes teardown(); host must call it | Fix redux mint race + env URL |
| SEC-84 WAF / edge | App has secureHeaders + per-user rate limit; no CSP on JSON API | Place WAF; lock origin; SOC feed |
SEC-72 — awp-api mint + ops
Mint contract
Sign HS256 with the same secret as chat JWT_SECRET (AW_CHAT_JWT_SECRET on AW side). Claims:
| Claim | Value |
|---|---|
userId or sub | AW user id |
exp | Required (TTL ≤ 1h recommended) |
iat | Required |
aud | aw-chat (must match chat JWT_AUD) |
iss | Stable issuer id (must match chat JWT_ISS) |
jti | Unique id per token (enables future revocation) |
Draft accounts: either refuse to mint, or mint with an explicit draft flag and have chat reject draft tokens (not implemented here — prefer refuse).
Chat host env (after mint ships)
REQUIRE_JWT_EXP=1
JWT_AUD=aw-chat
JWT_ISS=<same as mint iss>Secret rotation
Rotate AW_CHAT_JWT_SECRET / JWT_SECRET after any exposure in chats or tickets. Confirm old tokens fail verify. Prefer asymmetric (RS256, chat verify-only) as a follow-up; not required to close SEC-72 verify half.
Live retest (prove-by-identity A vs B)
- A registers device → B
DELETE /api/devices/<id>→ 404; A's row still present; A can still delete own → 204. - B
POST /api/csatwith A'sconversationId→ 403; no CSAT row linked to that conversation; no Intercom CSAT tag on A's thread.
SEC-76 — rn-app (client; not this repo)
Files cited in the finding (illustrative): shared-core/features/support-chat/ session thunk / slice / hooks; SUPPORT_CHAT_SERVER_URL hardcode.
CFX-1 — session token race
- Bind mint thunk to
(userId, generation). - Discard responses whose
userId≠ current account. - Store token keyed by account; never a process-wide singleton without generation.
CFX-2 — logout / account switch
- Clear support-chat redux + any persisted dev-mode flags on logout/switch.
- Call SDK
teardown()from@aw-chat/core(unregisters push + clears stores) before unmounting the widget.
Hardcoded DevStop URL
- Move
SUPPORT_CHAT_SERVER_URLto env / build config per stand. - Production must not hardcode a staging host after infrastructure handoff (DEV-549).
Acceptance: account switch during in-flight mint does not mount another user's chat credential; logout leaves no residual support-chat session.
SEC-84 — WAF / edge (infra)
WAF does not close SEC-72 or SEC-76 (object-authz / client state). Role: pre-launch DiD and virtual-patch for injection classes.
Acceptance sketch:
- Chosen WAF reverse-proxy in front of chat origin (detection-only → tune → blocking).
- Origin closed: direct hit bypassing the edge → timeout/403.
- CRS + coarse per-IP
limit_req; CSP/security-headers on web surfaces. - Audit JSON → Wazuh (SOC) per org ADR.
- Document in the ticket that SEC-72/76 remain app/backend fixes.
Stronger than WAF for the current findings: segment chat behind VPN / allowlist until public launch (SEC-41), plus the app fixes above.
Suggested owner routing
| Work | Owner |
|---|---|
| Deploy chat API with ownership + JWT env | Chat backend / DevStop handoff (DEV-549) |
| Mint claims + secret rotation | awp-api / SecOps |
| CFX-1/2 + URL | rn-app |
| WAF + origin lock | Infra (SEC-84) |
| Live A/B retest | SecOps after deploy |