Severity Daily

IT and AI security incidents, checked against the primary source

Tag: CVE-2026-12944

  • Langflow’s component scanner ran the code it was checking and returned ‘validated: true’; the fix shipped in June and the CVE arrived Monday

    Langflow’s component scanner ran the code it was checking and returned ‘validated: true’; the fix shipped in June and the CVE arrived Monday

    IBM’s bulletin says the scanner’s DANGEROUS_IMPORTS blocklist missed socket and urllib, so submitted code ran server-side during the check and the check reported success; the fix reached PyPI on June 23 and the CVE record arrived Monday evening.

    What happened

    NVD published CVE-2026-12944 on Monday, September 14, 2026, at 10:17 p.m. UTC — 5:17 p.m. Central — with vulnStatus of “Received.” IBM’s PSIRT scores it 9.6 with the vector CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N. The assigned weakness is CWE-918, server-side request forgery.

    The record’s description: “IBM Langflow OSS 1.0.0 through 1.10.0 can allow attackers to execute arbitrary Python code with root privileges (UID=0) on the Langflow server by submitting components containing socket or urllib imports.”

    The referenced IBM security bulletin is titled “Incomplete Security Scanner Blocklist Enables Network-Based Code Execution,” and its summary is the part worth reading closely. Langflow’s code security scanner maintains a blocklist named DANGEROUS_IMPORTS, intended to reject components that import modules capable of doing damage. That blocklist did not include socket or urllib. An authenticated user could therefore submit a component importing either one, and — in IBM’s account — the dangerous network operations “executed server-side during validation while returning a false ‘validated: true’ signal.” The bulletin lists the consequences as SSRF, reverse shells, and exfiltration of sensitive data.

    Two mechanics in that sentence matter separately. The first is that the code ran at all: validation was not a static inspection that decided whether to accept the component, it was an execution that happened before the decision. The second is that the decision came back positive. The control designed to catch dangerous components both ran the dangerous component and then marked it safe.

    IBM gives the affected range as Langflow OSS 1.0.0 through 1.10.0 and the remedy as an upgrade to 1.10.1, distributed through PyPI. It documents no workarounds. The bulletin credits KIM MINJUN, GitHub handle 31n6.

    The dates

    The bulletin’s change history has one entry: “02 Jul 2026: Initial Publication.” PyPI’s own upload records for the langflow package put 1.10.1 on the index at 2026-06-23T23:49:18 UTC. So the fixed build was publicly installable on June 23, 2026, the bulletin describing what it fixed appeared nine days later on July 2, and the CVE record that a scanner or an SBOM pipeline would key on arrived 83 days after the fix and 74 days after the bulletin.

    That gap is the reason this is a new story rather than an old one. Severity Daily covered nine Langflow CVEs on September 4, all of which trailed their bulletins by about a week. This one trailed by ten times that.

    Two further notes on the record as published. The 1.10.1 IBM names is not a current release: PyPI’s latest langflow is 1.12.1, uploaded on September 8, 2026, and eight stable releases separate it from the fix IBM points at. And the weakness class, CWE-918, describes SSRF — which is one of the things the bulletin lists, but the description in the same record says arbitrary Python code execution as root. A triage queue sorted on CWE will place this alongside a metadata-endpoint fetch, and the record’s own text says it is worse than that.

    Why it matters

    Langflow is a visual builder for LLM applications. Its unit of work is a component — a block of Python that a user writes or pastes into a flow. The entire product model is that users bring code and the platform runs it. A platform built that way has exactly one thing standing between a user and the host: the check that decides which code is acceptable. This CVE is a failure of that one thing, in two directions at once.

    Consider what the blocklist approach commits you to. DANGEROUS_IMPORTS is a deny list, which means its correctness depends on having enumerated every module that can reach the network, the filesystem, or a subprocess — and on doing so again every time Python’s standard library grows a way to do those things. socket and urllib are not exotic. They are the two most obvious network modules in the standard library, which is what makes their absence instructive rather than embarrassing: a deny list maintained by hand will be incomplete, and the only question is which entries are missing this quarter. An allow list of permitted imports fails closed when it is wrong. A deny list fails open.

    The false validated: true is the more serious half. A control that misses something leaves you where you would have been without it. A control that misses something and reports success leaves you worse off, because it has manufactured evidence. Anyone operating a shared Langflow instance between 1.0.0 and 1.10.0 has a log of validation results that says components were checked and passed. Those records are not a clean bill of health for the period; they are the output of a scanner that could return that answer for a component that had already opened a socket.

    The privileges tell the rest. PR:L means an authenticated user is required, which sounds like a meaningful barrier and often is not — a shared team instance of an AI flow builder typically has accounts for everyone who builds flows, and this is a privilege-escalation path from “can edit a flow” to root on the host. UID=0 in the description means the process runs as root, so the common containerized deployment offers no user-level separation between the flow runtime and the container. S:C, scope changed, is IBM’s own acknowledgment that the impact crosses out of the vulnerable component. The reverse shell and the credential theft the bulletin mentions are not the interesting consequences by themselves; the interesting consequence is that whatever the Langflow host can reach — internal APIs, databases, cloud metadata endpoints — an ordinary flow author could reach with a component that came back marked safe.

    There is no evidence of exploitation here, and none is claimed. What there is instead is a long quiet window: three months in which the fix existed, the bulletin existed, and the machine-readable record that most organizations actually depend on did not. An organization that upgraded through the summer for other reasons is fine and never knew there was anything to know. An organization that pins versions and upgrades on CVE signals learned about this on Monday evening.

    What to do

    Determine your installed langflow version. If it is 1.0.0 through 1.10.0, you are in the affected range. IBM’s stated fix is 1.10.1; the current release is 1.12.1, and unless something specific pins you to the 1.10 line, 1.12.1 is the version to move to, since taking 1.10.1 today means accepting a build from late June and none of the fixes since.

    There is no workaround, so the upgrade is the remediation. Until it lands, the practical mitigation is access: an instance where component authoring is restricted to a small, trusted set of accounts is a much smaller problem than one where any team member can add a component.

    Do not treat past validation results as assurance. If you retain flow or component history from an affected version, the components submitted in that window are worth a look — specifically for imports of socket or urllib in components that were accepted. That is a narrow, checkable question with a clear answer, and it is the closest thing to a compromise assessment available without host-level logs.

    Separately, check what the Langflow process can reach. If it runs as root in a container with broad network access to internal services, the upgrade closes this path and leaves the shape of the blast radius unchanged for the next one. Egress restrictions and a non-root runtime are the durable answer for a platform whose job is running code that users bring.

    Sourcing note

    Checked: the NVD record for CVE-2026-12944 for publication time, status, CVSS vector and score, CWE, affected range, and description; IBM’s security bulletin at ibm.com/support/pages/node/7278919 for the title, the DANGEROUS_IMPORTS mechanism, the “validated: true” wording, the affected versions, the 1.10.1 remedy, the absence of workarounds, the change-history date, and the credit; and PyPI’s JSON API for the langflow package for the 1.10.1 upload timestamp and the current release. All quotations are from the NVD record or the IBM bulletin.

    Unresolved: IBM does not say why the CVE record trailed the bulletin by 74 days, and no exploitation has been reported by IBM or observed publicly. The bulletin does not state whether the fix replaced the deny list with a different approach or simply added the two missing modules, and that distinction determines whether the next standard-library network module reopens the same hole; this page could not establish it from the bulletin text. The affected range ends at 1.10.0, so releases on the 1.11 and 1.12 lines are outside it, but IBM has not stated the fix’s presence in those lines explicitly.