Hidden Assumptions in saleor

12 assumptions this code never checks · 4 critical · spanning Temporal, Ordering, Environment, Domain, Scale, Contract, Resource

Every codebase relies on things it never checks. Most of them are routine. CodeSea looked at saleor/saleor and picked out the few most likely to cause trouble. The full list is just below.

Most of what this code assumes is routine. These 3 are the ones most likely to cause trouble here. The rest are minor; they're under "Show everything".

Worth your attention first

If an app token is revoked or an app is deactivated after being cached, the system continues serving the cached app_id for up to 30 days, granting access to unauthorized apps

Worth your attention first

Tokens could be matched to wrong apps during authentication, leading to permission escalation or wrong app context in requests

Worth your attention first

App installation fails silently or times out if the manifest server is temporarily unavailable, DNS fails, or network partitions occur during installation

Show everything (9 more)
Domain

Semantic version parsing for requiredSaleorVersion assumes standard NPM version format, but the custom RequiredSaleorVersionSpec.Parser changes prerelease policy from 'same-patch' to 'natural' without validating this change is safe

If this fails: Version compatibility checks may incorrectly allow incompatible app versions to install, leading to runtime errors when apps use unsupported API features

saleor/app/manifest_validations.py:clean_manifest_data
Scale

30-day cache timeout is appropriate for all deployment scenarios, regardless of security requirements, token rotation policies, or app lifecycle management needs

If this fails: In high-security environments requiring frequent token rotation, cached tokens remain valid far longer than intended, and in high-churn environments, cache may accumulate stale entries consuming memory

saleor/graphql/app/dataloaders/app.py:CACHE_TIMEOUT
Contract

The last_4s_to_raw_token_map structure correctly groups tokens by their last 4 characters, but tokens with identical last 4 chars could lead to incorrect cache invalidation of valid tokens

If this fails: Valid app tokens may be incorrectly removed from cache when other tokens sharing the same last 4 characters are invalidated, causing unnecessary database hits and authentication delays

saleor/graphql/app/dataloaders/app.py:AppByTokenLoader.remove_not_valid_tokens_from_cache
Resource

10MB icon file size limit is enforced consistently across all storage backends and network transfer scenarios, but no validation is shown for actual downloaded icon size before processing

If this fails: Apps could submit manifests with icons exceeding the limit, consuming excessive bandwidth and storage during download, or worse, causing memory exhaustion during image processing

saleor/app/installation_utils.py:MAX_ICON_FILE_SIZE
Contract

The database_connection_name parameter defaults to main database, but checkout operations assume this connection has write permissions and consistent read-after-write semantics

If this fails: If read replicas are configured as the default connection, checkout operations may fail with permission errors or encounter stale data after writes, corrupting order creation workflow

saleor/checkout/fetch.py:CheckoutLineInfo
Domain

App permissions are validated against the Permission model's current state, but no check ensures that permission assignments remain valid when permission definitions change in Saleor updates

If this fails: Apps may retain permissions that no longer exist or have changed meaning after Saleor upgrades, potentially granting unintended access or breaking app functionality

saleor/app/models.py:App
Temporal

MD5 hash provides sufficient uniqueness for cache keys across all possible tokens, but hash collisions could occur with large numbers of tokens over time

If this fails: Hash collisions would cause different tokens to share the same cache entry, leading to apps being authenticated with wrong credentials and potential data leakage between apps

saleor/graphql/app/dataloaders/app.py:create_app_cache_key_from_token
Environment

The __version__ import provides the current Saleor version in a format compatible with semantic version parsing, but version string format changes could break compatibility checks

If this fails: If Saleor version format changes (adding build metadata, changing prerelease format), app compatibility validation may fail incorrectly, blocking valid app installations

saleor/app/manifest_validations.py:RequiredSaleorVersionSpec
Resource

DataLoader cache is cleared after each GraphQL request completes, but no explicit memory cleanup is shown for large result sets or long-running requests

If this fails: Memory usage could grow unbounded during complex GraphQL queries that load large datasets, especially if requests are long-running or if cache cleanup fails

saleor/graphql/core/dataloaders:DataLoader

See the full structural analysis of saleor: the pipeline, data models, and system behavior that put these assumptions in context.

Full analysis of saleor/saleor →

Frequently Asked Questions

What does saleor assume that could break in production?

The one most likely to cause trouble: Cache data is valid if the cached_token_id matches the current token_id, regardless of when the app token was revoked or the app was deactivated If this fails, If an app token is revoked or an app is deactivated after being cached, the system continues serving the cached app_id for up to 30 days, granting access to unauthorized apps

How many hidden assumptions does saleor have?

CodeSea found 12 assumptions saleor relies on but never validates, 4 of them critical, spanning Temporal, Ordering, Environment, Domain, Scale, Contract, Resource. Most are routine — the analysis flags the two or three most likely to actually bite.

What is a hidden assumption?

Something the code depends on but never checks: a data shape, an ordering, an environment condition, a scale limit, or a contract with another service. It holds until the world it runs in changes, then fails silently.