By Yair Knijn · October 28, 2025
Two tenants, one misconfigured directory, and a cross-customer file leak
A CISO signs off on a shared transfer host because the vendor's diagram shows each customer landing in its own folder: /tenants/acme/inbound, /tenants/globex/inbound, distinct owners, distinct group ACLs. It reads as multi-tenant, so folder-level separation gets accepted as the isolation boundary and the review moves on.
That acceptance is the trap. Directory permissions are a configuration, not a boundary. They sit one chmod, one stray symlink, or one path-traversal bug away from putting Acme's filenames in Globex's listing. In regulated data, a filename alone can be reportable.
Folder permissions versus enforced tenant isolation
Folder separation makes a conditional promise: tenant B's files sit in a different path than tenant A's, and the OS denies access if the permission bits are right. That "if" carries the whole boundary. The OWASP Multi-Tenant Security Cheat Sheet makes the point: isolation has to live at a layer the tenant request cannot influence, and per-tenant filtering bolted onto a shared component is the classic place it quietly fails. Permission bits are exactly that kind of filter.
Enforced isolation survives a misconfiguration. You get there with separate accounts, separate storage scopes, and a transfer engine that resolves tenant_id from the authenticated session and refuses any path outside it, whatever the filesystem ACL says that morning. One wrong setting then costs you noisy logs, not a breach.
How a single misconfiguration crosses the boundary
The crossings are mundane. A restore resets a directory to mode 0755 and any authenticated SFTP user can ls a sibling tenant's inbound folder. The rest are variations:
- Permission drift after a restore, a patch, or a umask change
- A chroot or jail boundary set one directory too shallow
- Symlinks and hard links that escape the intended subtree
- Path traversal (
../, encoded separators, normalized Unicode) in the transfer or web layer
None of these need a sophisticated attacker. They need one tired operator and a Tuesday. The same engineer who would never put two tenants in one database table will happily put them in one filesystem with adjacent folders, because the folder metaphor feels safe in a way the table never did.
Why regulated buyers test isolation instead of taking your word
A bank or insurer running DORA due diligence does not read your architecture PDF and tick a box. They send a pen tester who stands up two test tenants and walks from one to the other with relative paths, symlinks, and a restored backup mid-test to catch drift. If folder permissions are your only wall, the exercise ends with tenant B's listing pasted into the report. Under GDPR, a cross-customer exposure of regulated personal data starts a 72-hour notification clock the moment you can no longer rule it out, and "we think the ACL held" does not rule it out.
This is why "logically separated" loses deals. To a careful buyer the phrase signals shared infrastructure with application-level filtering, the exact pattern they are paid to assume has a bypass. They want proof the boundary holds when the config is wrong.
Architecting isolation a pen test can't defeat
Make the boundary something a misconfiguration cannot cross. Give each tenant its own scoped storage and credential context, derive the allowed path from the authenticated identity rather than a folder ACL, and refuse symlinks across tenant roots. Canonicalize every path before it touches the filesystem and check it against the tenant scope. Log access with the resolved tenant, so a crossing attempt surfaces as a denied event, not a silent success.
In xEvolve, a tenant is an Environment with its own isolated storage scope and credential boundary, so a fat-fingered permission or a stray symlink fails closed instead of leaking a listing into someone else's dataset. If your isolation story is "we set the folder permissions carefully," that is the claim a pen test exists to break. See how the boundary is enforced on our security page.