Security release
This release fixes two vulnerabilities that let one tenant reach another
tenant's data when an untrusted user can influence a tenant's schema_name.
- Cross-tenant database access via long schema names (GHSA-6j59-h5h9-h29f,
high). PostgreSQL truncates identifiers to 63 bytes, but schema names were
limited to 63 characters. A name made of multi-byte characters could
truncate to an existing tenant's schema name, giving the new tenant read and
write access to that tenant's data, and deleting it could drop that tenant's
schema. - Cross-tenant template cache collision (GHSA-3xv4-2p82-gc3w, medium). The
cached template loader keyed entries as<schema>-<template>, so tenants
acmeandacme-basecould be served each other's templates.
Affected: 3.4.1 – 4.0.2. All users should upgrade.
See the advisories for full details, impact and mitigations.
Upgrade notes
- Schema names must now be at most 63 bytes in UTF-8. ASCII names are
unaffected. A tenant whose name is longer than 63 bytes was already sharing a
truncated schema name in PostgreSQL; it will now raiseValidationError.
One such row also stopsmigrate_schemasfor all tenants, so find and
remove these rows before upgrading; the advisory explains how. Do not delete
them withforce_dropor rename them. - Schema names are now validated whenever a tenant row is inserted or its
schema name changes. django-tenants refuses to drop a schema by an invalid
name or clone into one, and refuses to rename a schema whose current name is
over 63 bytes; other legacy names can still be renamed withrename_schema. - The cached template loader's cache keys change from
<schema>-<template>to
<schema>/<template>, and are now prefixed underschema_context()and the
public schema too. This only matters if you read the loader's cache
directly.
Other
parse_tenant_config_path()raisesSuspiciousFileOperationrather than
TypeErrorwhen no schema is set.