CVE-2026-105636 Overview
CVE-2026-105636 is a Server-Side Request Forgery (SSRF) [CWE-918] vulnerability in Plane, an open-source project management tool. The flaw affects the webhook delivery task in apps/api/plane/bgtasks/webhook_task.py in versions prior to 1.4.0. While Plane's validate_url() blocks private, loopback, link-local, and reserved addresses for the registered webhook URL, the delivery task calls requests.post() without allow_redirects=False and never re-validates the final destination after HTTP redirects. Authenticated users who can create a workspace can abuse this to pivot requests to internal services, including cloud instance metadata, and read responses through the workspace webhook-logs API.
Critical Impact
Any workspace creator can exfiltrate internal network data and cloud metadata credentials by registering a webhook that redirects to internal endpoints, with responses retrievable via the webhook-logs API.
Affected Products
- Plane (makeplane/plane) versions prior to 1.4.0
- Plane self-hosted deployments exposing workspace webhook functionality
- Plane instances running on cloud providers with Instance Metadata Service (IMDS) endpoints reachable from the worker
Discovery Timeline
- 2026-10-05 - CVE-2026-105636 published to NVD
- 2026-10-07 - Last updated in NVD database
Technical Details for CVE-2026-105636
Vulnerability Analysis
The flaw is a classic SSRF caused by trusting a one-time URL validation while allowing unrestricted HTTP redirects. Plane's webhook subsystem validates the user-supplied webhook URL through validate_url(), which rejects private, loopback, link-local, and reserved IP ranges. However, the background delivery task invokes requests.post() with default redirect behavior, so a 302 response from an attacker-controlled host causes the Python requests library to transparently follow the redirect to any internal address.
The worker then stores the response body in webhook_logs. The workspace webhook-logs API exposes those logs to the attacker, turning the SSRF into a readable, two-way data channel. On cloud deployments, this includes IMDS endpoints such as AWS http://169.254.169.254/latest/meta-data/, enabling retrieval of IAM role credentials.
Root Cause
The root cause is incomplete URL validation across the request lifecycle. validate_url() is only applied to the originally registered webhook target. The HTTP client follows redirects by default and does not re-run validate_url() against intermediate or final URLs. There is also no network-layer egress filtering preventing the worker process from reaching link-local or RFC1918 addresses.
Attack Vector
An attacker with permission to create a workspace registers a webhook pointing to a public server they control. When Plane triggers the webhook, the attacker's server returns an HTTP 302 to an internal URL such as http://169.254.169.254/latest/meta-data/iam/security-credentials/. The Plane worker follows the redirect, fetches the internal response, and persists it in webhook_logs. The attacker reads the captured body through the webhook-logs API.
# Patch excerpt from apps/api/plane/authentication/adapter/base.py
# Replaces direct `requests` usage with a hardened fetch helper
# that re-validates URLs across redirects.
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: https://github.com/makeplane/plane/commit/04622ce1188c4680951f0001e35efb342fe51615
Detection Methods for CVE-2026-105636
Indicators of Compromise
- Webhook registrations whose public target responds with 3xx redirects to RFC1918, loopback, or link-local addresses such as 169.254.169.254.
- Entries in webhook_logs containing response bodies that resemble cloud metadata, IAM credentials, or internal service banners.
- Outbound requests from Plane worker hosts to 169.254.169.254, metadata.google.internal, or 169.254.170.2.
- Repeated webhook creation and deletion by a single workspace user correlated with unusual webhook-log reads.
Detection Strategies
- Inspect Plane application logs for webhook delivery responses that follow redirects, and alert when the final response host differs from the registered host.
- Monitor the webhook-logs API for high-volume reads shortly after webhook creation events.
- Correlate egress network flows from Plane worker containers against an allowlist that excludes link-local and private ranges.
Monitoring Recommendations
- Enable DNS query logging on the Plane worker to detect lookups of internal hostnames triggered by webhook deliveries.
- Capture and retain cloud VPC flow logs for Plane worker subnets to identify SSRF attempts against IMDS.
- Alert on IMDSv1 token-less requests originating from the Plane worker and migrate to IMDSv2 where supported.
How to Mitigate CVE-2026-105636
Immediate Actions Required
- Upgrade Plane to version 1.4.0 or later, which introduces pinned_fetch_following_redirects to re-validate URLs across redirects.
- Rotate any cloud IAM credentials, API tokens, or secrets reachable from the Plane worker's network position.
- Audit existing webhook_logs for responses containing metadata, credentials, or other internal service data.
Patch Information
The fix is included in Plane release v1.4.0 and tracked in GitHub Pull Request #9163 and commit 04622ce. Full details are available in the GitHub Security Advisory GHSA-mq87-52pf-hm3h and GitHub Release v1.4.0.
Workarounds
- Enforce IMDSv2 on AWS instances hosting Plane workers to require session tokens for metadata access.
- Apply network egress policies that block Plane worker pods from reaching 169.254.0.0/16, RFC1918 ranges, and loopback addresses.
- Restrict workspace creation to trusted users until the upgrade is applied.
# Example Kubernetes NetworkPolicy snippet blocking IMDS egress for Plane workers
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: plane-worker-block-metadata
spec:
podSelector:
matchLabels:
app: plane-worker
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 169.254.0.0/16
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
- 127.0.0.0/8
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

