CVE-2026-104976 Overview
Plane is an open-source project management tool affected by a Server-Side Request Forgery (SSRF) vulnerability [CWE-918] in versions prior to 1.4.0. The application validates the GITEA_HOST environment variable only for URL scheme and does not reject hosts resolving to private or internal IP addresses. Four outbound requests in the Gitea OAuth flow are derived from this unvalidated host and skip the validate_url() check. Additionally, the avatar_url field is pulled from the Gitea user profile, which allows user-controlled external URLs. An attacker with a Gitea account on a legitimately configured instance can trigger server-side requests to internal targets.
Critical Impact
Authenticated attackers can coerce the Plane backend into issuing arbitrary outbound HTTP requests to internal infrastructure, enabling internal network reconnaissance and access to metadata endpoints.
Affected Products
- Plane (makeplane/plane) versions prior to 1.4.0
- Self-hosted Plane deployments with Gitea OAuth enabled
- Plane instances configured with an administrator-defined GITEA_HOST
Discovery Timeline
- 2026-10-05 - CVE CVE-2026-104976 published to NVD
- 2026-10-06 - Last updated in NVD database
Technical Details for CVE-2026-104976
Vulnerability Analysis
The vulnerability resides in Plane's Gitea OAuth integration. The administrator-configured GITEA_HOST value is passed through a scheme-only validation step and used directly for outbound requests during the OAuth handshake. Because the host is never resolved and checked against private, loopback, or link-local address ranges, Plane will attempt requests to any internal endpoint reachable from the backend.
A second attack path involves the avatar_url field returned by the Gitea user profile API. Gitea permits users to configure external avatar URLs on their own profiles. When a Plane user authenticates through Gitea, Plane fetches the avatar from the attacker-controlled URL without passing it through validate_url().
Root Cause
The root cause is incomplete URL validation in the OAuth adapter. The scheme check accepts any http or https host without resolving the hostname or comparing it to a denylist of internal address ranges. Both the host-level requests and the per-user avatar_url fetch bypass the central validate_url() function, violating the project's own SSRF protection boundary.
Attack Vector
Exploitation requires an administrator to enable Gitea OAuth against a legitimate Gitea instance. A low-privileged attacker who can register on that Gitea instance sets their profile avatar to an internal URL such as a cloud metadata service address. On login through Gitea, the Plane backend fetches the avatar from the attacker-supplied internal URL. The attack vector is network-based and requires only low privileges on the OAuth provider.
# Patch excerpt - apps/api/plane/authentication/adapter/base.py
import uuid
from io import BytesIO
-import requests
from django.conf import settings
from django.core.exceptions import ValidationError
from django.core.validators import validate_email
+from plane.utils.url_security import pinned_fetch_following_redirects
# Django imports
from django.utils import timezone
Source: GitHub Commit 04622ce
The fix replaces the plain requests library with pinned_fetch_following_redirects from plane.utils.url_security, which enforces URL validation and safe redirect handling before each outbound call.
Detection Methods for CVE-2026-104976
Indicators of Compromise
- Outbound HTTP requests from the Plane backend to RFC1918 ranges, loopback interfaces, or cloud metadata endpoints such as 169.254.169.254.
- Gitea OAuth login events immediately followed by backend requests to non-Gitea hosts.
- Unusual DNS resolutions originating from the Plane API container targeting internal hostnames.
Detection Strategies
- Inspect egress proxy logs for Plane backend requests whose destination differs from the configured GITEA_HOST or Gitea profile domain.
- Correlate authentication events from the Gitea OAuth adapter with subsequent outbound HTTP calls to detect avatar-fetch SSRF chains.
- Audit the GITEA_HOST configuration for values that resolve to internal addresses or that lack explicit allowlisting.
Monitoring Recommendations
- Deploy egress filtering between the Plane backend and internal subnets, cloud metadata services, and management APIs.
- Enable verbose logging on the OAuth adapter module and ship logs to a central platform for correlation.
- Alert on repeated 4xx or connection-refused responses from the Plane backend to internal IP ranges, which indicate SSRF probing.
How to Mitigate CVE-2026-104976
Immediate Actions Required
- Upgrade Plane to version 1.4.0 or later, which introduces pinned_fetch_following_redirects for OAuth and avatar requests.
- If immediate upgrade is not possible, disable the Gitea OAuth login method in Plane until patched.
- Review the configured GITEA_HOST and ensure it points only to a trusted external Gitea instance.
Patch Information
The fix is included in Plane v1.4.0. The remediation hardens webhook, link, and OAuth-avatar flows against SSRF by routing all outbound requests through a URL security helper that validates destinations and controls redirect behavior. See the GitHub Security Advisory GHSA-hx79-5pj5-qh42, Pull Request #9163, and the v1.4.0 Release Notes.
Workarounds
- Place the Plane backend behind an egress proxy that blocks access to RFC1918, loopback, and link-local address ranges.
- Block outbound access from the Plane backend container to cloud metadata endpoints such as 169.254.169.254.
- Restrict which Gitea accounts can authenticate to Plane using Gitea organization membership controls.
# Example iptables egress restrictions for the Plane backend host
iptables -A OUTPUT -d 169.254.169.254 -j REJECT
iptables -A OUTPUT -d 10.0.0.0/8 -p tcp --dport 80 -j REJECT
iptables -A OUTPUT -d 10.0.0.0/8 -p tcp --dport 443 -j REJECT
iptables -A OUTPUT -d 172.16.0.0/12 -p tcp --dport 80 -j REJECT
iptables -A OUTPUT -d 192.168.0.0/16 -p tcp --dport 80 -j REJECT
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

