Security and IDOR
IDOR is enforced only on Core Backend and Middleware Backend. The User App and Front-facing SPAs are not a security boundary.
The site x-api-key used to list public menus is public (it ships in the browser). Do not recommend “frontend must hide the key” or “frontend must filter owned_by so strangers cannot see data.” If a public key can read or write another owner’s business, fix Core Backend API-key path settings (and Middleware if it proxies). If those settings are missing, recommend them on Core/Middleware — not a React/Nuxt checklist.
Who implements IDOR
| Layer | Role |
|---|---|
| Core Backend | API-key records: allowed_entities, method → read|create|update|delete, allowed_request_api_url_path_settings (wildcards, require_user_bearer_token, allowed_user / allowed_user_key_should_match vs owned_by). |
| Middleware Backend | Re-check JWT vs owned_by before file-manager and admin order update. Service key is server-only and must not impersonate. Guest place-order uses the service key; it may only notify the menu owner. |
| Frontend | How to build the screen: public key for guest GET, Bearer for owner writes. No IDOR implementation task. |
How to build API keys (Core Backend)
Create two keys. Do not give the browser the write key.
Public browse key (Front-facing + User App list)
Allow only public reads, for example:
GET .../entity/nellalink_business_menuand.../meta-key/{metaKey}for enabled menusGET .../entity/nellalink_business_menu_itemfor children of those menus
Deny on this key:
GET/PUT/DELETEnotifications, users, other owners’ businesses- All
POST/PUT/PATCH/DELETEentity writes require_user_bearer_token: false is OK for those GET paths only
Private / write key (never in the browser)
Used by Middleware (PLUGIN_NELLALINK_INIT_CORE_BACKEND_X_API_KEY) and any trusted server:
require_user_bearer_token: true on owner writes- Paths for create/update business, menu, item, notifications
- Server sets
owned_byfrom JWT (file-manager) or from the menu owner (place-order), not from a guest-chosen uuid
Frontend writes that still go directly to Core (v1 login, create business) need a JWT-required key, or move those writes to Middleware. If Core cannot require JWT per path today, recommend require_user_bearer_token on those paths.
Object rules
| Object | Public key may | JWT / Middleware may | Must deny |
|---|---|---|---|
| Enabled menu + items | Yes (read) | Owner CRUD | PUT/trash others |
nellalink_business list of others | Only if you intend a public directory | Owner CRUD own | PUT others |
| Notifications | No | Owner of userUuid | Any other user |
| Users | No (except own after login) | Own uuid | Other users |
| File upload / admin order update | No | Middleware + JWT owner | Impersonation |
Known gap
Generic GET .../entity/{type}/{uuid} may return a row to any valid key. Must-fix on Core (path deny for notifications and private businesses on the public key). Not a frontend ticket.
Iteration sign-off (Core + Middleware only)
- [ ] Public browse key cannot read/write notifications or other users
- [ ] Write paths require JWT;
owned_bymatches token - [ ] Middleware cannot write Core as another user
- [ ] Place-order service key only notifies the menu owner
- [ ] If a control is missing, recommend it on Core path settings or Middleware — do not assign IDOR to frontend