Severity Daily

IT and AI security incidents, checked against the primary source

Tag: AI agents

  • IBM’s seventeen Langflow CVEs landed in three waves today, naming two different fix versions, and two of its identifiers still have no record

    IBM’s seventeen Langflow CVEs landed in three waves today, naming two different fix versions, and two of its identifiers still have no record

    Eight more IBM Langflow CVE records published this afternoon after the nine this site covered at midday, in a third wave pointing at a different fix version — and a second bulletin identifier turns out to have no record either.

    What happened

    This morning Severity Daily reported that nine IBM Langflow OSS CVE records reached NVD at 4:17 p.m. UTC on Friday, September 4, 2026, seven days after the IBM security bulletins that described the fixes. That was accurate about the nine. It was not the whole day. Seventeen Langflow records were published to NVD between 3:17 and 5:17 p.m. UTC, in three distinct waves, and eight of them were not in that story.

    An NVD keyword query for Langflow bounded to today returns totalResults of 17:

    • 3:17 p.m. UTC — three records. CVE-2026-8447 (6.1, stored cross-site scripting in the Playground chat interface), CVE-2026-9138 (6.5), and CVE-2026-9186 (6.5, IP spoofing through untrusted proxy headers). Affected range 1.0.0 through 1.11.2. These landed an hour before the nine and were missed; a correction has been appended to the earlier story.
    • 4:17 p.m. UTC — nine records. CVE-2026-19298 through CVE-2026-19306, the batch already covered. Affected range 1.0.0 through 1.11.2.
    • 5:16 p.m. UTC — five records. CVE-2026-14470 (6.5), CVE-2026-17621 (5.4), CVE-2026-17622 (6.5), CVE-2026-17627 (4.9), and CVE-2026-17631 (5.0). Affected range 1.0.0 through 1.10.2 — a different upper bound from the other twelve.

    That different bound is not an error in the records. It points at a second line of bulletins. IBM bulletin 7285644, “Langflow OSS is affected by server-side request forgery due to missing URL validation in flow components,” gives affected versions “1.0.0-1.10.2” and this remediation: “IBM strongly recommends addressing the vulnerability now by upgrading Langflow OSS to version 1.10.3.” Its change history reads “28 Aug 2026: Initial Publication” — the same date as the bulletins telling operators to go to 1.11.3.

    So on August 28, IBM published Langflow bulletins naming two different fix versions, and on September 4 it flushed the CVE records for both into NVD inside two hours.

    The third wave also includes a bulletin that is not from August 28 at all. Bulletin 7286293, “Langflow OSS is affected by arbitrary file read due to path traversal vulnerabilities in file and knowledge base components,” carries the change history “03 Sep 2026: Initial Publication.” It covers CVE-2026-14470, CVE-2026-17621, and CVE-2026-17622, and its records were published to NVD the following day. Affected versions “1.0.0-1.10.2,” fix “version 1.10.3,” workarounds and mitigations “None.”

    The lag, in other words, is not seven days. It is seven days for one set and one day for another, both arriving in the same batch. What synchronized them was the flush, not the bulletin.

    Finally, the orphan count has gone up. This morning’s story noted that bulletin 7285639 prints CVE-2026-12766 with a CVSS score of 5.4, and that NVD returns totalResults: 0 for it. Bulletin 7285644 prints CVE-2026-12765 at CVSS 6.5, described as an SSRF that “may allow an unauthenticated attacker to send unauthorized requests from the system.” NVD returns totalResults: 0 for that identifier too. Both remain absent as of this writing, a week after the bulletins that print them.

    None of the seventeen records published today names a fixed version. The affected range stops, and the record is silent about where to go.

    Why it matters

    The two-fix-version split is the part that will cost somebody an afternoon, and it is worth being precise about why, because the obvious reading is wrong.

    Nothing here asks anyone to downgrade. The 1.10.3 bulletins describe bugs fixed earlier in the 1.10 line; an operator running 1.11.2 already has those fixes, and 1.11.3 is still the version to be on. The problem is that nothing in the record system says so. A CVE record for CVE-2026-17631 states an affected range ending at 1.10.2 and names no fix at all. The bulletin behind it says 1.10.3. A remediation ticket generated from either artifact, against a fleet running 1.11.x, produces a version number lower than what is already installed. Somebody has to work out by hand that the two bulletin families are stacked rather than parallel, and there is no field anywhere in the chain that encodes that relationship.

    This compounds the arithmetic problem this publication described this morning. An operator who read IBM’s earlier August 28 bulletins upgraded to 1.11.2 and was, for a week, one version short of the vendor’s own line. An operator who now reads the 1.10.3 bulletins without noticing they belong to a superseded branch may conclude that 1.10.3 is the target and that 1.11.2 is more than sufficient. Both errors come from the same missing piece: the CVE record does not name a fixed version, so every remediation decision has to be reconstructed from vendor prose.

    The three-wave structure matters for a different reason. It is evidence about how this queue actually behaves, and it undercuts a tempting generalization. “IBM PSIRT runs about a week behind its bulletins” is a usable heuristic if it is true; today it is true of twelve records and false of three, with a September 3 bulletin’s records arriving faster than an August 28 bulletin’s. The observable pattern is a queue that drains on its own schedule and carries whatever is in it. Anyone building alerting on top of vendor bulletin dates should assume records arrive in unrelated clumps, and should not read a batch boundary as a meaningful grouping. The three waves today separate by publication mechanics, not by severity, product line, or bug class.

    Two orphan identifiers is a materially different fact from one. A single CVE ID printed on a bulletin with no record behind it reads as a clerical slip. Two, from the same vendor, in the same week, on the same product, printed with CVSS scores and full descriptions, looks like a step in the process that does not always complete. Both of these are also, notably, the unauthenticated ones in their respective bulletins — CVE-2026-12765 is described as exploitable without credentials, and it is the identifier with no record. That is almost certainly coincidence, and it is stated here as coincidence, but it is the pair a defender would least want missing from a scanner feed.

    The practical consequence is unchanged from this morning and worth restating once: for anything keyed on CVE identifiers — scanners, SBOM tooling, vendor feeds, risk dashboards — a Langflow inventory was incomplete until this afternoon and is still incomplete by two identifiers. The vendor bulletin remains the authoritative document, and reading ibm.com by hand remains the only way to see the whole picture.

    What to do

    • Upgrade Langflow OSS to 1.11.3. That remains the target for anything on the 1.11 line, and it supersedes the 1.10.3 guidance in the second bulletin family. Do not act on a ticket that names 1.10.3 as a target for a 1.11.x install.
    • Re-scan after your feed refreshes. None of these seventeen identifiers existed in NVD this morning, and five of them were published within the last five hours. A scan run earlier today is stale.
    • Track CVE-2026-12765 and CVE-2026-12766 by hand. Both are printed on IBM bulletins with scores; neither exists in NVD. They will not appear in any CVE-keyed tooling until the records are created, and the 6.5 SSRF is the unauthenticated one.
    • Read the bulletin, not the record, for the fix version. None of the seventeen records names one.
    • IBM lists no workarounds or mitigations on any of these bulletins. The entire remediation is the upgrade.
    • There is no claimed exploitation of any of the seventeen. The separately tracked CVE-2026-0768, the unauthenticated code execution flaw with observed exploitation against VulnCheck canaries, is still not among IBM’s records and remains scoped to version 1.4.2 alone.

    Sourcing note

    The seventeen records and their publication timestamps come from an NVD keyword query for Langflow bounded to September 4, 2026, which returned totalResults of 17. CVE-2026-17631 and CVE-2026-8447 were retrieved individually to confirm their timestamps, affected ranges, and source identifier of [email protected]. The absence of CVE-2026-12765 and CVE-2026-12766 was checked by direct cveId query; both returned totalResults: 0. An absence reported by a single retrieval is not proof of absence, and these will be re-checked; CVE-2026-12766 has now returned zero on two separate days.

    Bulletin titles, change-history dates, affected version tables, remediation sentences, and the “None” mitigation entries are quoted from IBM support pages 7285644, 7285646, and 7286293 as read today. Node 7286293 is dated “03 Sep 2026: Initial Publication”; nodes 7285644 and 7285646 are dated “28 Aug 2026.” IBM has not published anything explaining the relationship between the 1.10.3 and 1.11.3 bulletin families, and the reading offered here — that the 1.10 fixes are contained in the 1.11 line — is inference from the version numbering, not a vendor statement. It should be confirmed against IBM before it is relied on for a large upgrade. Whether the two missing identifiers are withheld, delayed, or abandoned is not stated anywhere and is unresolved.

    Sources: NVD, Langflow records; IBM bulletin 7286293; IBM bulletin 7285644; IBM bulletin 7285646.

  • Google’s Agent Development Kit read any file for an unauthenticated caller, and the CVE landed 239 days after the fix

    Google’s Agent Development Kit read any file for an unauthenticated caller, and the CVE landed 239 days after the fix

    A CVE published this morning describes an unauthenticated arbitrary file read in Google’s Agent Development Kit; the code was fixed on January 8, 2026, and the record landed 239 days later with a changelog link for an advisory.

    What happened

    Google Cloud published CVE-2026-79707 at 11:17 a.m. UTC on Friday, September 4, 2026. The description is short and unambiguous: “A Path Traversal vulnerability in the builder endpoint in Google Cloud Agent Development Kit (ADK) versions 1.9.0 through 1.21.0 on Python allows an unauthenticated remote attacker to read arbitrary files using a crafted file_path query parameter.”

    Google scores it CVSS v4.0 8.7, High, on the vector AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N, with a Provider Urgency of Amber. The weakness is CWE-22. The affected package is google-adk on PyPI, from 1.9.0 up to but not including 1.22.0.

    The record carries two references and no advisory: a link to a heading in the project’s CHANGELOG.md, and a link to the commit. There is no Google Cloud security bulletin for it. There is no GitHub Security Advisory for it either — the GitHub Advisory Database listing for google-adk currently carries two entries, GHSA-rg7c-g689-fr3x (CVE-2026-4810, code injection and missing authentication, April 13, 2026) and GHSA-8qg5-x5vm-75jx (CVE-2026-18236, July 29, 2026), and this is neither of them.

    The code is public, so the timeline can be checked rather than inferred. Package upload times from PyPI: 1.9.0 was published July 31, 2025; 1.21.0, the last affected release, on December 12, 2025; and 1.22.0, which contains the fix, on January 8, 2026. The current release is 2.8.0, from August 26, 2026. The vulnerable window ran roughly five months. The gap between the fix shipping and the CVE describing it is 239 days.

    Downloading both wheels and reading the source shows exactly what the bug was. In 1.21.0, google/adk/cli/fast_api.py registers this route:

    @app.get("/builder/app/{app_name}", response_class=PlainTextResponse)
    async def get_agent_builder(app_name: str, file_path: Optional[str] = None, tmp: Optional[bool] = False):
        base_path = Path.cwd() / agents_dir
        agent_dir = base_path / app_name
        ...
        agent_file_path = agent_dir / file_path
        if not agent_file_path.is_file():
            return ""
        else:
            return FileResponse(path=agent_file_path, media_type="application/x-yaml", ...)

    The caller’s file_path goes straight into a path join and then into a FileResponse. The route declares no authentication dependency; a search of that module for Depends(, dependencies=, bearer, or API-key handling returns nothing.

    Two separate ways out of the directory follow from that one line. The obvious one is ../. The quieter one is that agent_dir / file_path uses pathlib’s join operator, and joining an absolute path discards the left-hand side entirely: Path("/agents/app") / "/etc/passwd" evaluates to /etc/passwd. No traversal sequence is needed, and a filter that only looks for .. would not see it. The media_type is set to application/x-yaml, but the response body is whatever the file contains.

    The fix in 1.22.0 addresses both. It adds _parse_file_path(), which rejects a path that starts with / and any path with a .. component; _has_parent_reference(); _get_app_root(), which validates the app name and confirms the resolved root stays under the agents directory; and _resolve_under_dir(), which resolves the final path and checks is_relative_to() before returning it. That is a correct fix, applied at four layers.

    The commit that carries it is titled “fix: Harden YAML builder tmp save/cleanup.” In the 1.22.0 release notes it sits in a list of bug fixes, between “Avoid local .adk storage in Cloud Run/GKE” and “Handle overriding of requirements when deploying to agent engine.” Nothing in the message, the changelog line, or the release notes says security, path traversal, or file disclosure.

    Why it matters

    The reflex reading is that this is a development server and therefore does not matter. That reading is wrong on two counts, and both are checkable in Google’s own materials.

    First, the vulnerable route is registered inside get_fast_api_app(), unconditionally. The function takes a required web parameter, and it is natural to assume the builder endpoints belong to the browser UI that flag controls. They do not. They are added after the base app is constructed, outside the if web: block, so they exist whether or not the web interface is being served. Running headless does not remove them.

    Second, get_fast_api_app() is not an internal detail. It is the function Google’s own Cloud Run deployment guide instructs developers to call from their main.py:

    from google.adk.cli.fast_api import get_fast_api_app
    app: FastAPI = get_fast_api_app(agents_dir=AGENT_DIR, session_service_uri=SESSION_SERVICE_URI,
                                   allow_origins=ALLOWED_ORIGINS, web=SERVE_WEB_INTERFACE)

    The same page’s example deployment command ends with --allow-unauthenticated, documented there as “Allows public access to the service. Remove this flag for private services.” Anyone who followed that guide between August 2025 and January 2026 and did not remove the flag put an unauthenticated arbitrary file read on the public internet, in a container that by construction holds agent configuration, and usually service-account material and API keys alongside it.

    There is a second detail in the version history worth noticing. When the endpoint first appeared in 1.9.0, it was decorated @working_in_progress("builder_get is not ready for use.") — the project’s own marker for code that is not meant to be relied on. By 1.21.0 that decorator is gone from the module entirely, while the unsafe path join is unchanged. The route was promoted out of work-in-progress status without the input handling being revisited. That is a specific and common failure mode: the guard rail that made the risk acceptable was the label, and the label was removed as a cleanup.

    The disclosure shape is the last thing, and it is the part that generalizes. Google Cloud published a second CVE from the same CNA at the same minute today: CVE-2026-4644, a privilege escalation in Integration Connectors, which does have a bulletin — GCP-2026-059, dated September 4, 2026 — and which says, in full, “No customer action is required. This vulnerability was patched on December 11, 2025.” For a managed service that is a defensible disclosure: Google fixed it in the fleet nine months ago, nobody has anything to do, and the CVE is a matter of record.

    ADK is not a managed service. It is a package a developer pins in a requirements file, and Google cannot upgrade it on anyone’s behalf. A team that pinned google-adk==1.20.0 last fall and has not moved since has been exposed for the entire period, is exposed right now, and until this morning had nothing in any feed to tell them. The two CVEs got the same treatment on the same day; only one of the two products could absorb it. The one that could not is the one that got a changelog anchor instead of an advisory.

    What to do

    • Upgrade google-adk to 1.22.0 or later. Current is 2.8.0. Anything from 1.9.0 through 1.21.0 is affected; 1.8.0 and earlier do not carry the read route at all.
    • Check what you actually run, not what you last installed. pip show google-adk in the running image; grep -r "google-adk" requirements*.txt pyproject.toml poetry.lock uv.lock across repositories. Pinned versions in container images are the ones that will be missed.
    • Find exposed deployments before you finish the upgrade. For Cloud Run: gcloud run services get-iam-policy SERVICE --region REGION and look for allUsers on roles/run.invoker. Anything ADK-derived and publicly invokable should be closed or put behind authentication now, independent of the package upgrade.
    • Test for it directly. On a build you control, request /builder/app/<app>?file_path=/etc/passwd against the service. A patched build returns an empty body and logs a rejection; a vulnerable one returns the file.
    • Treat credentials in reach of the process as exposed if the service was publicly invokable during the window. Service-account keys, model API keys, and anything in a mounted secret file were all readable by an unauthenticated caller who knew a valid app name.
    • There is no known exploitation of this CVE, and no exploit code has been published. It is not on the KEV catalog and carries no federal deadline.

    Sourcing note

    The CVE record was read from NVD at services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-2026-79707: published September 4, 2026 at 11:17 a.m. UTC, last modified at 4:18 p.m. UTC, source identifier f45cbf4e-4146-4068-b7e1-655ffc2c548c (Google Cloud). Release dates for 1.9.0, 1.21.0, 1.22.0, and 2.8.0 are PyPI upload timestamps, read from the registry API rather than from the changelog. The vulnerable and fixed code was read from the 1.21.0 and 1.22.0 wheels downloaded from PyPI and unpacked locally; the 1.9.0 wheel was unpacked to confirm the @working_in_progress decorator and the introduction of the endpoint, and 1.8.0 to confirm the read route is absent there. Quotations of the code are from those files. The Cloud Run guidance and the --allow-unauthenticated example are quoted from Google’s ADK documentation.

    GCP-2026-059 and its “No customer action is required” sentence are quoted from Google Cloud’s security bulletins page. The statement that no GitHub Security Advisory exists for this CVE reflects the advisory database listing for google-adk as of publication; one may be added later. Google has not said who reported the bug, whether it was found internally or externally, or whether it was ever exploited; none of those are asserted here. Whether the eight-month gap between the January fix and today’s record was a backlog, a late external report against already-fixed code, or a deliberate delay is not stated anywhere in the record and is unresolved.

    Sources: NVD, CVE-2026-79707; google/adk-python commit 6f259f0; google-adk on PyPI; ADK Cloud Run deployment guide; Google Cloud security bulletins.