Severity Daily

IT and AI security incidents, checked against the primary source

Tag: vLLM

  • Two Monday deadlines outrank a day of nines and a seventeen-record batch

    Two Monday deadlines outrank a day of nines and a seventeen-record batch

    Eleven stories ran today, and the loudest of them were loud on the numbers: a 10.0, two 9.9s, a pair of 9.8s on a perimeter VPN appliance, and seventeen CVE records for one project landing in the same minute. None of that is what to deal with first. Two flaws already on CISA’s Known Exploited Vulnerabilities catalog come due Monday, September 14 — ConnectWise ScreenConnect and GitLab — and both carry BOD 26-04’s forensic-triage obligation, which means a federal agency has to remediate inside the window and also determine whether the asset was already compromised. That is about 48 hours, on the weekend, and it is the only thing on today’s wire with a clock attached. A 9.8 with a patch available can wait until Monday morning; these two cannot. The ScreenConnect item is also the one most likely to be misread: the flaw is in the client, not the server, so cloud-hosted customers told “no action is required” for their server still have to update every host client and access agent they run.

    The day had a thread, and it was GitLab. One patch release, September 10, produced three separate stories in eighteen hours, and the vendor supplied none of the new facts in any of them. Overnight, the CISA coordinator block attached to the NVD record marked exploitation “active” while GitLab’s own advisory said nothing about exploitation at all. By the afternoon the catalog itself carried Thursday’s addition and Monday’s deadline — a date this site declined to report twelve hours earlier and has since corrected on the story that got it wrong. And by evening the record for a second flaw in the same release, CVE-2026-87719, named the two things the release notes had left out: the entry condition is an authenticated user with Duo Chat access, not an administrator, and what they come away with is Advanced Search instance configurations and credentials.

    After the deadlines, the perimeter. Check Point’s two 9.8s let an unauthenticated attacker run code on a VPN appliance, and neither record names a fixed version — the boundary is a Jumbo Hotfix take number, and the Spark appliance line the advisories cover is missing from the records entirely. Frontegg SAML SSO accepts unsigned SAML responses at 9.8 with no fix at all, the plugin having been closed on WordPress.org on September 4. The Events Calendar took three releases to close two unauthenticated 9.8 remote code execution flaws on a plugin installed on more than 600,000 sites, and no changelog line says so.

    Below that, three records that describe a flaw better than they describe a remedy. AVideo’s seventeen all draw the affected line at the same git commit hash, with the last tagged release dating to April 2024. vLLM and Socket Firewall make an unflattering pair, because in both the thing that failed was the safeguard: a trust_remote_code flag that vanished into **kwargs, and a firewall that did not verify TLS to the registries it exists to police. Flatpak’s Critical sandbox escape waited 32 days for an identifier, and the one Flatpak CVE issued in the meantime was a different bug.

    Still open at the end of the day: NVD’s record for the GitLab 10.0 does not carry cisaExploitAdd or cisaActionDue, so the single most authoritative machine-readable source an operator is likely to query still does not say the flaw is on KEV with a deadline two days out. GitLab has said nothing about exploitation since the patch release. Frontegg has no fixed version to offer, AVideo has no release to upgrade to, and Check Point’s records still omit Spark.

  • vLLM ran attacker model code with trust_remote_code set to False, and the CVE arrived 17 days after the fix

    vLLM ran attacker model code with trust_remote_code set to False, and the CVE arrived 17 days after the fix

    One model loader handed the safety flag to a function that never accepted it, the argument vanished into **kwargs, and untrusted model code ran anyway.

    What happened

    NVD published CVE-2026-90553 at 1:16 p.m. UTC on Saturday, September 12, 2026. The record is still marked Received, which means NVD has not completed its own analysis; every score on it belongs to VulnCheck, the CNA that assigned the identifier.

    The description, verbatim: “vLLM before 0.28.0 contains a remote code execution vulnerability in the LlavaOnevision2 processor loader that ignores the trust_remote_code parameter when loading remote processor classes. Attackers can craft a malicious model with arbitrary code in processing_llava_onevision2.py that executes with vLLM process authority even when trust_remote_code is set to False.”

    vLLM is an open-source inference server for large language models, widely deployed for self-hosted serving. The project does not publish deployment counts, and no figure in circulation is verifiable from a primary source, so this story gives none.

    The mechanism is set out in the project’s own advisory, GHSA-3c86-2m5g-59q7, published August 28, 2026. The _load_ov2_processor function loads remote processor classes through transformers.dynamic_module_utils.get_class_from_dynamic_module(). It passes a trust_remote_code argument. The transformers function does not take that argument, so it lands in **kwargs and is discarded. GitHub’s advisory says it plainly: the parameter “is silently ignored via **kwargs.” vLLM ships a wrapper, try_get_class_from_dynamic_module, that resolves the trust setting before calling through. The LlavaOnevision2 path called the raw transformers function instead.

    GitHub rates the flaw High at 7.8, with the vector CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H. VulnCheck carries that same v3.1 vector and score on the NVD record, and adds a CVSS v4.0 score of 8.5 from the vector CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N. The weakness is CWE-94. GitHub states the impact as “Arbitrary Python execution with vLLM process authority when loading untrusted community models, undermining the security intent of the trust_remote_code=False safety setting.” The reporter is credited as NLx64, with jperezdealgaba as coordinator.

    The fix shipped first. PyPI’s release metadata puts vllm 0.28.0 on the index at 10:07 a.m. UTC on August 26, 2026 — two days before the advisory, and seventeen days before the CVE record. Version 0.29.0 followed on September 9. Until yesterday afternoon, GitHub’s advisory carried the line “No known CVE.”

    Two companion records landed in the same batch, at the same minute. CVE-2026-90554 covers versions 0.10.2 through 0.28.0 and reads: “vLLM versions >=0.10.2 and <0.28.0 do not apply any audio decode-size or duration limit when extracting audio from video input for NanoNemotronVL models.” It is CWE-400, scored 6.2 under v3.1 and 6.9 under v4.0, and it applies only where use_audio_in_video=True. CVE-2026-90555 reads: “vLLM versions before 0.28.0 fail to validate audio sample rate headers in the transcription endpoint, allowing authenticated clients to bypass duration checks. Attackers can submit forged FLAC headers with inflated sample rates to trigger excessive memory allocation and crash the API server process affecting all tenants.” It is CWE-409, scored 6.5 under v3.1 and 7.1 under v4.0.

    No source checked reports exploitation. Neither GitHub nor VulnCheck claims any, and none of the three CVEs appears in the Known Exploited Vulnerabilities catalog.

    Why it matters

    The control that failed is the one the ecosystem tells operators to rely on. Pulling a model from a public hub means downloading weights and, for some architectures, Python. trust_remote_code is the boundary between those two things. It is the flag that appears in every hardening guide for self-hosted inference, the one an auditor asks about, the one a platform team sets to False in a base image and considers the question closed. For one model family, an operator who did exactly that got arbitrary code execution anyway.

    The bug class deserves attention beyond this one project. A keyword argument was passed to a function that does not accept it and was absorbed by a catch-all. Python raises nothing. Linters raise nothing when the callee’s signature ends in **kwargs. Code review sees a call site that reads correctly, because it does read correctly — the argument is right there in the source. A test asserting “the model loads” passes. The test that would have caught this asserts that a hostile model fails to load, and that is the test almost nobody writes. This publication keeps running into the same shape: a guard that exists, reads as intended, and does nothing at runtime. It is a failure mode that survives every review that looks at the code rather than at the behavior.

    Then there is the fifteen-day gap between the advisory and the identifier. This is not a complaint about volunteer labor; it is a description of what two different scanners told two different organizations running the same software. A team using GitHub-native tooling was told on August 28. A team whose software composition analysis keys on CVE IDs sourced from NVD — which is most vulnerability-management and most compliance reporting — was told nothing until yesterday. Both scans were working correctly. Both answers came from a maintained database. One of them was wrong for a little over two weeks, and the organization holding it had no way to know that from inside its own tooling. Any vLLM scan performed between August 28 and September 12 that returned clean should be treated as unrun.

    The scoring vector is worth a second look, not because it is wrong but because of the picture it paints. AV:L with UI:R describes a person sitting at a machine who chooses to load a particular model. A good many vLLM deployments are not shaped like that. The model is a string in a configuration file. A container pulls it on startup. An autoscaler pulls it again on every new node. In that shape the required user interaction happened once, months ago, when somebody edited a YAML file, and every subsequent load is automatic. The score is defensible on its own terms. The mental image it produces — a developer at a laptop, one deliberate action, local access — is not the one that applies to a production inference fleet that resolves model names against a public hub on every scale-out event.

    Finally, the shape of the batch. All three records are in multimodal handling: audio extraction from video, sample-rate headers on a transcription endpoint, and a vision-language processor loader. Inference servers have been growing codecs, container parsers, and dynamic class loading at speed, and in doing so they have inherited the bug classes that media handling has carried for thirty years. Two of these three are memory-exhaustion crashes reachable through a decoder. That is not an AI problem. That is a parser problem that has arrived inside AI infrastructure, and it will keep arriving.

    What to do

    Upgrade to vllm 0.28.0 or later; 0.29.0 has been on PyPI since September 9. That single release closes all three records.

    If you cannot upgrade immediately, note that the code execution path requires loading a LlavaOnevision2 model. Audit which model families your serving configuration permits, and pin models to a vetted internal mirror rather than resolving names against a public hub at runtime. CVE-2026-90554 applies only to NanoNemotronVL models with use_audio_in_video=True, so check that configuration key directly. CVE-2026-90555 requires an authenticated client, which makes it a tenant-against-tenant problem on shared endpoints; cap request body size at the proxy and rate-limit the transcription route.

    Stop treating trust_remote_code=False as a sufficient control on its own. Run the server as an unprivileged user, in a container that has no cloud credentials mounted and no token that can write to your model registry, so that a loader bug costs you a process rather than a supply chain.

    Re-run your dependency scan against vLLM. If your tooling reads NVD, it acquired these three identifiers yesterday afternoon and not before.

    Sourcing note

    Checked: the NVD records for CVE-2026-90553, CVE-2026-90554, and CVE-2026-90555, all published at 1:16 p.m. UTC on September 12, 2026, and all carrying vulnStatus of Received; the vLLM project’s GitHub Security Advisories GHSA-3c86-2m5g-59q7, GHSA-936p-m5pv-vvjf, and GHSA-99f2-hwrc-gvq8; VulnCheck’s advisory page for the LlavaOnevision2 flaw; and PyPI’s release metadata for the vllm package, used as the primary source for release upload timestamps. CISA’s website returns 403 to automated fetching, so the Known Exploited Vulnerabilities catalog was read from the cisagov/kev-data GitHub mirror, catalog version 2026.09.11, released at 7:32 p.m. UTC on September 11 with 1,709 entries; none of these three CVEs is in it. Could not reach: GitHub’s REST API returned 403, so release dates come from PyPI and from the advisory pages themselves rather than from release objects. Unresolved: neither the project nor VulnCheck explains why the identifiers were assigned fifteen days after the advisory, and no source checked reports exploitation of any of the three.