Guide chapters
Security boundaries in a marketplace
The problem#
A marketplace has one property an ordinary store does not: parties who should not see each other data work inside the same system, and they are not the operator employees. A seller is an external user with panel access.
That changes the nature of the risk. The most serious ones are not outside attacks but a user reaching something that is not theirs.
Five boundaries that actually break#
| Boundary | Typical break |
|---|---|
| Data between sellers | a new view queries without filtering by owner |
| Seller versus operator | a seller endpoint takes the identifier from the request |
| User-generated content | an uploaded file served from the same domain as the panel |
| Provider events | accepting a webhook without verifying the signature |
| Integration credentials | seller keys stored next to ordinary data |
Minimum version#
- The data owner derived from the session, never from a client-supplied parameter.
- Owner filtering in the data access layer, not in the view.
- Signature verification on every incoming provider event.
- Integration credentials stored apart from the rest of the seller data.
- User files served from a different domain than the panel.
What not to build yet#
- Your own abuse detection system.
- Granular per-resource, per-action permissions.
- Scanning uploaded files with your own rules.
- An access log for every record.
Plan ahead#
Isolation as the default behaviour#
A query for seller data should default to their data, and reaching anything else should require an explicit act. The opposite default means every new screen is an opportunity for a leak.
Signature verified before anything else#
An endpoint receiving provider events is public. Without signature verification it is an open door through which any operation that endpoint performs can be triggered.
Credentials as their own entity#
Keys to seller shops are the most sensitive data in the system, because they grant access to somebody else business. Kept alongside the profile, they end up in every export and every diagnostic dump.
Triggers#
- the first new view written by somebody who did not know the isolation rule;
- the first integration holding seller credentials;
- the first feature allowing a file upload;
- the first message between a buyer and a seller;
- a second team member with panel access.
Next stage#
After the first trigger: moving isolation below the view layer, if it is not there already. After the third: limiting file types and sizes and serving from a separate domain. After the fourth: basic protection against abuse of the messaging channel. After the fifth: roles, the simplest possible.
Common mistakes#
| Assumption | Why it costs |
|---|---|
| "The seller identifier comes from the request." | Swapping the identifier grants access to other people data. |
| "A filter in the view is enough." | The first new view without it exposes everything. |
| "The webhook comes from the provider." | A public endpoint without a signature accepts requests from anyone. |
| "Integration keys are an ordinary field." | They end up in exports and diagnostic dumps. |
| "User files can sit next to the panel." | An uploaded file executes in the context of your domain. |
What works in practice#
The only rule that genuinely prevents leaks is deriving the data owner from the session and constraining queries in the access layer. Anything that depends on remembering a filter while writing a new screen will fail at some screen.
Signature verification on incoming events is the second thing that cannot be added painlessly later, because by then the endpoint is live and somebody already depends on it.
Checklist#
- The data owner comes from the session, not the request.
- Isolation is enforced in the data access layer.
- Every incoming event has its signature verified.
- Integration credentials are stored separately.
- User files are served from a different domain than the panel.
I design multi-vendor platforms with onboarding, payments, moderation, and operational workflows.
Explore marketplace development