If you self-host Tandoor Recipes — the popular Django-based recipe manager with meal planning, shopping lists, and cookbook collections — you need to upgrade right now. CVE-2026-33152, disclosed March 26, carries a CVSS score of 9.1 (Critical) and lets any network attacker brute-force user passwords at full speed, with zero rate limiting and zero lockout risk.
This isn’t a theoretical risk. The vulnerability is trivial to exploit, requires no authentication, and works against every API endpoint in your Tandoor instance. Here’s what happened, why it matters, and exactly how to fix it.
What Is CVE-2026-33152?
Tandoor Recipes uses Django REST Framework (DRF) for its API layer and django-allauth for user authentication. AllAuth ships with a sensible rate limit: by default, ACCOUNT_RATE_LIMITS restricts login attempts to 5 per minute per IP address.
The problem? That rate limit only applies to the HTML login page at /accounts/login/. Every DRF API endpoint that accepts BasicAuthentication — which is the default authentication backend in Tandoor — bypasses AllAuth entirely. An attacker can send thousands of Authorization: Basic headers per second to any API endpoint and the server will happily check each one against the database.
The Technical Breakdown
Here’s how the authentication flow works in vulnerable versions (before 2.6.0):
- HTML login page (
/accounts/login/): AllAuth processes the request ? rate limit of 5 attempts/min/IP is enforced ? attacker gets locked out after 5 tries. - Any API endpoint (
/api/recipe/,/api/meal-plan/, etc.): DRF’sBasicAuthenticationprocesses theAuthorizationheader directly ? AllAuth rate limit is never consulted ? unlimited attempts at full speed.
The classification is CWE-307: Improper Restriction of Excessive Authentication Attempts. The CVSS 9.1 score reflects the combination of network-accessible attack vector, no privileges required, and the potential for full account compromise.
Why This Is Worse Than It Sounds
Brute-force vulnerabilities are often dismissed as “just password guessing.” This one is particularly dangerous for self-hosters because:
- No lockout whatsoever. The attacker can test passwords indefinitely. There’s no failed-attempt counter, no temporary ban, no CAPTCHA — nothing.
- Any API endpoint works. The attacker doesn’t need to find a specific login path. Any authenticated endpoint (recipes, meal plans, shopping lists) accepts the Basic auth header and validates it.
- Usernames are often guessable. Many self-hosted instances use
admin, the owner’s first name, or an email address. Tandoor’s default setup doesn’t randomize usernames. - Most self-hosted instances lack a WAF. Unlike SaaS apps behind Cloudflare or AWS WAF, a Tandoor instance on a home server or VPS typically sits behind only a reverse proxy — which doesn’t inspect authentication headers for brute-force patterns.
- Shared credentials compound the risk. If the Tandoor admin reuses the same password for their server SSH, reverse proxy dashboard, or other self-hosted apps, a single cracked password cascades across the entire homelab.
Who Is Affected?
Every Tandoor Recipes installation running a version before 2.6.0 is vulnerable. The project has over 2,000 GitHub stars and is one of the most popular self-hosted recipe managers, commonly deployed via Docker on home servers, VPS instances, Unraid, and Synology NAS devices.
If you installed Tandoor from Docker Hub or the official Docker Compose file and haven’t updated since March 26, 2026, you’re running a vulnerable version.
How to Check Your Version and Upgrade
Step 1: Check Your Current Version
# Docker Compose deployment
docker compose exec web_recipes python -c "import recipes; print(recipes.VERSION)"
# Or check the container image tag
docker compose images | grep tandoor
If your version is below 2.6.0, you’re vulnerable.
Step 2: Upgrade to 2.6.0+
# Pull the latest image
docker compose pull
# Restart with the new version
docker compose up -d
# Verify the upgrade
docker compose exec web_recipes python -c "import recipes; print(recipes.VERSION)"
Important: Version 2.6.0 introduced a breaking change — you must now set the ALLOWED_HOSTS environment variable to your domain name. Without this, the application may reject requests. Add it to your .env or docker-compose.yml:
# .env file
ALLOWED_HOSTS=recipes.yourdomain.com
Step 3: Verify the Fix
After upgrading, test that brute-force attempts are now blocked:
# Send 10 rapid failed login attempts to any API endpoint
for i in $(seq 1 10); do
curl -s -o /dev/null -w "%{http_code}
" -u "admin:wrongpassword$i" https://recipes.yourdomain.com/api/recipe/
done
On a patched instance, you should see 429 Too Many Requests responses after the rate limit threshold is reached. On a vulnerable instance, you’ll see 401 Unauthorized for every single attempt — the server happily processes them all.
Immediate Mitigations (If You Can’t Upgrade Yet)
If upgrading immediately isn’t possible, apply these mitigations to reduce your exposure:
1. Rate-Limit at the Reverse Proxy
If you’re running Caddy, Nginx, or Traefik in front of Tandoor, add rate limiting for requests containing Authorization headers:
Nginx example:
# In your nginx.conf http block
limit_req_zone $binary_remote_addr zone=tandoor_auth:10m rate=5r/m;
# In your server block
location /api/ {
limit_req zone=tandoor_auth burst=5 nodelay;
proxy_pass http://tandoor:8080;
}
2. Restrict Network Access
If Tandoor is only used by your household, restrict access to your WireGuard VPN or local network. This eliminates the remote attack vector entirely.
3. Use Strong, Unique Passwords
Even unlimited brute-force attempts won’t crack a 20+ character random password in any reasonable timeframe. Use a password manager and ensure every Tandoor account has a unique, high-entropy password.
4. Deploy Fail2Ban or CrowdSec
Tools like Fail2Ban or CrowdSec can detect and block brute-force patterns at the firewall level, adding a defense layer even when the application itself doesn’t rate-limit.
The Bigger Lesson: Django DRF BasicAuthentication Is a Footgun
CVE-2026-33152 isn’t unique to Tandoor. It’s a pattern that affects any Django application that combines AllAuth (or similar rate-limited login views) with DRF’s BasicAuthentication backend. The OWASP Django REST Framework Cheat Sheet explicitly warns about this:
Django’s basic authentication backend checks the Django users database and queries built-in permissions, but does not provide protection against brute force attacks via any rate limiting mechanism.
If you maintain or self-host any Django + DRF application, audit your authentication stack:
- Check if
BasicAuthenticationis in yourDEFAULT_AUTHENTICATION_CLASSES. - If yes, verify that DRF’s
DEFAULT_THROTTLE_CLASSESinclude rate limiting for authentication attempts — not just your login view. - Consider replacing
BasicAuthenticationwith token-based or session-based authentication for API endpoints, which don’t transmit credentials on every request. - Add django-defender or
django-axesfor application-level brute-force protection that covers all authentication paths.
Timeline
| Date | Event |
|---|---|
| March 26, 2026 | CVE-2026-33152 publicly disclosed (CVSS 9.1) |
| March 26, 2026 | Tandoor Recipes 2.6.0 released with fix |
| March 27, 2026 | Tandoor Recipes 2.6.1 follow-up release |
Bottom Line
CVE-2026-33152 is a textbook example of why self-hosted applications need the same security attention as production SaaS. A missing rate limit on API endpoints turned every Tandoor instance into an open invitation for credential stuffing.
Upgrade to Tandoor Recipes 2.6.0 or later today. Set ALLOWED_HOSTS. While you’re at it, put your instance behind a VPN or at minimum a rate-limiting reverse proxy, and make sure you’re not reusing that password anywhere else.
Need a VPS with proper network isolation for your self-hosted apps? Canadian Web Hosting’s Cloud VPS gives you dedicated resources and full root access to configure firewalls, reverse proxies, and VPN tunnels exactly the way you need them. For hands-off security, our Managed Support team handles patching, monitoring, and hardening so you can focus on cooking.
Be First to Comment