NIST deprecates RSA-2048 from 2030. Find every one of them before attackers do.
🐍
🐍 PyPI
Not in CISA KEV
MEDIUM severity

CVE-2026-77433 — kiwitcms

MEDIUMFix: kiwitcms/Kiwi#4458

CVE-2026-77433 is a medium-severity (CVSS 6.1) vulnerability in kiwitcms. The records list no fixed version yet; check the vendor advisory below and apply the mitigations in the meantime.

Kiwi TCMS account confirmation open redirect through protocol-relative URLs

Published
Updated
Affected
1 pkg
Patched
See advisory
Exploits
None indexed
Exploitation data as of Nov 9, 2026 · OSV.dev, FIRST.org (EPSS)

Real-World Exposure

1 pkg affected
🐍kiwitcms

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects PyPI packages — download data is not available via public APIs for these ecosystems.

Description

Summary

In Kiwi TCMS version 16.1, the fix for CVE-2026-54724 (open redirect via unvalidated next parameter) in the account confirmation endpoint is incomplete. The validation uses startswith("/") to check if the redirect URL is local, but this is bypassed by protocol-relative URLs like //evil.com which start with / but redirect the browser to an external attacker-controlled domain. 16.1’s incomplete mitigation still allows protocol-relative destinations and earlier releases lack the mitigation.

Vulnerable Code

In tcms/kiwi_auth/views.py, the Confirm view (line ~113):

def get_redirect_url(self, *args, **kwargs):
    self.url = self.request.GET.get("next", reverse("core-views-index"))
    if not self.url.startswith("/"):
        self.url = reverse("core-views-index")

The check startswith("/") passes for //evil.com because it begins with /, but browsers interpret //evil.com as a protocol-relative URL that redirects to https://evil.com (or http://evil.com depending on the current page's protocol).

Proof of Concept

GET /confirm/<activation_key>/?next=//evil.com/phishing HTTP/1.1
Host: kiwi.example.com

Response:

HTTP/1.1 302 Found
Location: //evil.com/phishing

The browser follows the redirect to https://evil.com/phishing.

Verification:

>>> url = "//evil.com/phishing"
>>> url.startswith("/")
True  # passes the check!

Impact

An attacker can craft a confirmation link that, after the user confirms their account, redirects them to a phishing page. This is useful for:

  • Credential phishing (fake login page on attacker domain)
  • Malware delivery after trusted action
  • Social engineering (user trusts the link because it's from the legitimate Kiwi TCMS instance)

The attack requires sending a crafted activation link to a user who is registering, or intercepting/predicting the activation key.

Suggested Fix

Use Django's url_has_allowed_host_and_scheme() utility instead of a simple startswith check:

from django.utils.http import url_has_allowed_host_and_scheme

def get_redirect_url(self, *args, **kwargs):
    self.url = self.request.GET.get("next", reverse("core-views-index"))
    if not url_has_allowed_host_and_scheme(
        self.url,
        allowed_hosts={self.request.get_host()},
        require_https=self.request.is_secure(),
    ):
        self.url = reverse("core-views-index")

This properly rejects protocol-relative URLs, absolute URLs to other hosts, and other bypass patterns.

Fixed in Version 16.2

Affected Packages

1 total
EcosystemPackageVulnerable rangeFix
🐍PyPIkiwitcmsall versionsNo fix

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for kiwitcms, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Remediation status

    The records we use list no patched version of kiwitcms for CVE-2026-77433. Check the maintainer's advisory, and where your build allows, override or pin the dependency away from the vulnerable range.

  3. Mitigate without a patch

    Stop reflecting attacker-controlled destinations: resolve every redirect target against an allowlist of paths or hosts you own, prefer a server-side key over a full URL in the request, and reject absolute URLs entirely where the flow only ever needs a relative one.

Frequently Asked Questions

## Summary In Kiwi TCMS version 16.1, the fix for CVE-2026-54724 (open redirect via unvalidated `next` parameter) in the account confirmation endpoint is incomplete. The validation uses `startswith("/")` to check if the redirect URL is local, but this is bypassed by protocol-relative URLs like `//evil.com` which start with `/` but redirect the browser to an external attacker-controlled domain. 16.1’s incomplete mitigation still allows protocol-relative destinations and earlier releases lack the mitigation. ## Vulnerable Code In `tcms/kiwi_auth/views.py`, the `Confirm` view (line ~113):
O3 Security · Impact-Aware SCA

Is CVE-2026-77433 in your dependencies?

Find it across PyPI, including transitive dependencies.