Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallA tenant ID that arrives in a header, query string, URL path or request body is a request: “I would like to act in tenant X.” It does not show that the caller is allowed to. If your server reads that value and uses it to pick data, you have a selector with no check behind it, and any signed-in user can try other tenants’ values.
OWASP’s Multi-Tenant Security Cheat Sheet puts it this way: “Treat client-supplied tenant identifiers as selectors only. Verify that the authenticated principal is authorized to act in the selected tenant.” This article covers what that check looks like, where it must be enforced, how to compare isolation designs, and how to test it.
As an Amazon Associate I earn from qualifying purchases.
Why a valid login and a valid tenant ID still aren’t enough
Two separate questions must both be answered on every request, and a client-supplied tenant ID answers neither:
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitches- Is this principal entitled to act in this tenant right now? This is current membership, or authorization for a service account.
- Is this principal allowed to perform this operation on this specific resource? This is object-level authorization.
Authentication only proves who the caller is. OWASP’s IDOR guidance and Authorization Cheat Sheet both stress that each request touching an object needs a permission check for that object and that operation. Checking only an identifier or the object’s type can expose another tenant’s records.
#1 Best Overall
The attack in one example
A user in tenant acme calls GET /api/invoices/8841 with the header X-Tenant-Id: acme. They change the header to globex, or change the invoice number. If the handler runs SELECT * FROM invoices WHERE id = 8841, or trusts the header for scoping, the response may contain another tenant’s invoice. This is a classic Insecure Direct Object Reference (IDOR), applied across tenant boundaries.
Random IDs are not a fix
Opaque identifiers such as UUIDs make enumeration harder. OWASP is explicit that they are not an authorization control. An ID that leaks through a log, a shared link, an email or a support ticket still works if the permission check is missing.
The correct flow
- Establish identity on the server. Derive the principal from a verified session or token, not from request fields.
- Resolve the tenant context the principal may use. Look up their current membership (or, for services, their authorization). If a user belongs to several tenants, the client’s value can only request a switch. The server confirms the switch is permitted.
- Bind that verified context to the request. Downstream components should receive the server-verified context and must not be able to override it with unverified input.
- Authorize the action on the resource. Check that the principal may perform this operation on this object within this tenant.
A client-sent tenant value can legitimately be compared with the trusted context, and rejected if they differ. It must never be the thing that creates the context.
Recommended Free Tools
Scope every lookup to the tenant
For tenant-owned objects, the lookup or policy must include both the object and the authorized tenant context. An unscoped fetch by resource ID is unsafe whenever it can return an object owned by another tenant. Illustratively:
- Unsafe:
find(invoice_id), then hope a later check catches a mismatch. - Safer:
find(invoice_id, tenant = ctx.tenant), wherectx.tenantcomes from the verified request context, followed by a check of the specific operation.
Enforce this at a boundary that every tenant-owned access path crosses, such as a tenant-scoped repository layer or a central policy point. Scattering ad hoc checks across handlers leaves gaps. Data-layer safeguards add defense in depth by limiting the damage when application code forgets a check.
Don’t stop at the route handler
Tenant isolation fails at the paths people forget. Review each of these:
Rank #3
Alternate routes and internal calls
Older API versions, bulk endpoints, export and administrative actions, and service-to-service calls often reach the same data without the same checks. Internal callers should pass the verified context, not a raw tenant ID.
Caches
A cache key that omits tenant scope can serve one tenant’s value to another. Include tenant scope in the key, and authorize before serving a protected cached value.
Files, object storage and signed URLs
Storage paths and filenames are caller-controlled references too. Issue a signed URL only after authorizing the exact object and operation. Once issued, the URL carries the access.
Rank #4
Asynchronous jobs
A tenant ID inside a queued message is not proof that the producer was authorized or that the consumer should trust it. Re-establish authorization at the consumer.
Choosing an isolation mechanism
OWASP does not name one architecture as universally correct. It presents database and infrastructure isolation as design choices and recommends enforceable controls suited to the risk. The options are:
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →| Option | What enforces the boundary | If app code omits a check |
|---|---|---|
| Application policy only | Checks in code | Largest exposure; nothing else stops the query |
| Tenant-scoped repository or query layer | Shared data-access code adds tenant scope | Protected on paths that use the layer; raw queries bypass it |
| Database row-level security (RLS) | Database policies on shared tables | Database still filters rows, if context is set correctly |
| Schema or credential separation | Per-tenant schema or database credentials | Limited by what the credentials can reach |
| Physical separation | Separate infrastructure per tenant | Smallest blast radius; highest operational cost |
Compare them on five axes: strength of the enforceable boundary, coverage of every data access path, blast radius when a check is missed, operational complexity (including safe context handling under connection pooling and async work), and fit to the data’s sensitivity and your threat model.
Best Value
If you use PostgreSQL row-level security
RLS is an implementation option for shared tables, not a requirement. OWASP calls out two cautions:
- Request-time database roles must not bypass RLS.
- Tenant context must be set carefully per transaction, especially with pooled connections, so one request’s tenant setting never carries over to the next.
Also inventory every tenant-owned table so none is left without a policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.How to test it
- Create at least two principals in different tenants, each with their own resources.
- Authenticate as one and substitute the other’s tenant value or object reference.
- Try every operation that applies: read, create, update, delete, export and administrative actions. All should be denied.
- Vary where the reference sits: path segments, query strings, bodies and filenames.
- Hit alternate endpoints and data paths, not only the primary route.
- Test pooling if you use RLS tenant settings: confirm context doesn’t leak between requests on a reused connection.
- Repeat after changes to caching, queries, service boundaries or shared resource handling.
Tests must pass even when IDs are unguessable. A test that only tries sequential numbers will wrongly pass an opaque-ID system that has no real check.
Free tools Windows power users keep installed
One-click scans. No signup required.
Review checklist
- Tenant context comes from verified identity and current membership, never directly from a request field.
- Tenant-switch requests are validated against membership.
- Every tenant-owned lookup carries tenant scope and an operation-level check.
- Cache keys include tenant scope.
- Signed URLs are issued only after authorizing the specific object and operation.
- Queue consumers re-authorize rather than trusting message contents.
- Exports, admin tools and internal services follow the same rules.
- Cross-tenant tests exist for each operation and run on changes.
The guidance here draws on OWASP’s Multi-Tenant Security, IDOR Prevention, Authorization and Authorization Patterns cheat sheets, and its Web Security Testing Guide chapter on insecure direct object references. Those sources describe the mechanism and controls but do not publish a prevalence figure for this class of flaw, so none is claimed here.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




