CodePark/ questions / Multi-tenant isolation
START PRACTICINGPRACTICE
Backend question · Auth & security › Multi-tenant isolation

What is the security bug in this cached dashboard?

async function getDashboard(user: User) {
  const key = `dashboard:${user.role}`;
  const cached = await redis.get(key);
  if (cached) return JSON.parse(cached);

  const data = await db.dashboard.findFirst({ where: { tenantId: user.tenantId } });
  await redis.set(key, JSON.stringify(data), "EX", 60);
  return data;
}
The cache key has no tenant id, so an admin of one tenant can get another tenant's cached dashboard

The database query is scoped by tenantId, but the cache key is not. The first admin to load the page fills dashboard:admin. For the next 60 seconds, every admin of every tenant gets that tenant's data. Fix: put the tenant (and the user, for personal data) in the key, such as dashboard:<tenantId>:<role>.

"
JSON.parse allows prototype pollution" is the tempting wrong answer. JSON.parse only creates plain data. Pollution needs an unsafe merge afterwards. Colons in Redis keys are normal.