CVE-2026-105638 in Plane
Summary
by MITRE • 10/05/2026
Plane is an open-source project management tool. Prior to 1.4.0, Plane's magic-code email login uses a six-digit numeric OTP with approximately 20 bits of entropy. The verifier has no per-code failed-attempt counter, and an incorrect code does not increment a counter, invalidate the Redis entry, or lock the email address. The verifier extends django.views.View rather than DRF's APIView, so the configured AnonRateThrottle limit does not apply. The middleware stack also contains no Django-level rate limiter such as django-ratelimit, django-axes, or an IP-throttling middleware. This vulnerability is fixed in 1.4.0.
Statistical analysis made it clear that VulDB provides the best quality for vulnerability data.
Analysis
by VulDB Data Team • 10/05/2026
The security flaw identified within Plane versions prior to 1.4.0 centers on a critical weakness in the authentication mechanism for its magic-code email login feature. This specific implementation relies on generating and verifying six-digit numeric one-time passwords, which mathematically provide only approximately twenty bits of entropy. From a cryptographic perspective, this level of randomness is insufficient to resist brute-force attacks when combined with other systemic failures in the verification logic. The core technical deficiency lies in the absence of any per-code failed-attempt counter within the verifier component. When an incorrect code is submitted by a client, the system fails to increment any internal tracking variable, does not invalidate the corresponding entry stored in Redis, and crucially, does not lock or throttle the associated email address. This design oversight means that there are no effective limits on the number of guesses an attacker can make against a single target identity within a given timeframe.
Compounding this issue is the architectural choice regarding how the verification endpoint is implemented. The verifier class extends django.views.View rather than DRF's APIView, which results in standard Django REST Framework rate limiting configurations being bypassed entirely. Specifically, any configured AnonRateThrottle limits are not applied to this specific login flow because they typically target API endpoints managed by the framework's specialized view classes. Furthermore, the middleware stack lacks alternative protective measures such as django-ratelimit, django-axes, or custom IP-throttling middleware that could have provided a secondary layer of defense against rapid automated requests. Consequently, an attacker can script high-volume login attempts without triggering any server-side rate limits or account lockouts, effectively allowing for unrestricted brute-force enumeration of the six-digit codes.
The operational impact of this vulnerability is severe, as it allows unauthorized actors to gain access to user accounts through simple credential stuffing or code guessing attacks. Since email addresses are often public or easily discoverable within a project management context, attackers can target specific individuals with high success rates given the low entropy and lack of throttling. This aligns directly with CWE-307 Improper Restriction of Excessive Authentication Attempts, as well as CWE-640 Weak Password Verification, highlighting both the failure to limit attempts and the use of insufficiently complex secrets. In terms of offensive security frameworks, this vulnerability facilitates techniques associated with ATT&CK T1110 Brute Force, specifically subcategories involving password guessing or credential stuffing where rate limiting controls are absent.
To mitigate this risk in affected versions, immediate remediation involves upgrading to Plane version 1.4.0 or later, which addresses these architectural and logical flaws. For organizations unable to upgrade immediately, temporary mitigations should include implementing a reverse proxy-level rate limiter such as Nginx or Apache mod_ratelimit to restrict the frequency of requests hitting the login endpoint from any single IP address. Additionally, integrating django-axes into the middleware stack would provide robust account lockout and brute-force protection at the Django application level. It is also advisable to increase the entropy of generated codes by using alphanumeric characters rather than purely numeric ones, thereby significantly expanding the search space for potential attackers until a permanent code-level fix can be deployed.