Severity Daily

IT and AI security incidents, checked against the primary source

Tag: ESPnet

  • Seven of today’s nine stories describe a fix that never reaches the running install

    Seven of today’s nine stories describe a fix that never reaches the running install

    The most important thing published today is not the day’s highest score. HAProxy CVE-2026-90678 is a 7.5, against a 9.8 for sngrep’s stack overflow. HAProxy outranks it on where it sits and on what a reader can do about it. A remote, unauthenticated HTTP/3 client can desynchronize reused backend connections, slip requests past a frontend deny rule, and swallow other users’ Authorization headers — at the edge, in front of everything behind it. And the fix is a commit, not a release: 3.3.14 and 3.4.4 are the newest builds on their maintained branches and both sit inside the affected range, which makes “update to the latest version,” the advice most coverage will give, wrong. sngrep’s 9.8 is real, but it is a terminal SIP viewer an operator points at traffic by hand, the blast radius is one workstation, and its fix is likewise a commit on master that no tagged release and no Debian package carries.

    There is a thread, and it is the day’s actual story. In seven of the nine stories published today, a fix exists somewhere other than in something you can install. HAProxy’s and sngrep’s are commits. snappy-java’s 7.5 out-of-bounds write has no fix at all — the newest artifact on Maven Central was published in July 2025 and is the top of the affected range. LangBot 4.10.11 generates its new recovery key only when none exists, so upgrading leaves an existing installation holding the 24-bit secret the release was cut to replace. ESPnet’s patched release raises an error below PyTorch 2.6 while its own metadata still declares torch>=2.3.1, so an install that satisfies the declared dependencies gets a fixed path that throws and unfixed paths that run. Nodemailer’s denial of service was introduced by the security fix in 9.1.0 and repaired only in 10.x, so a 9.x user has to cross a major version to escape it. And Really Simple Security’s fix has been auto-updating to three million sites since September 1 under a changelog line that reads like a display bug: the code arrived, the reason to care did not.

    Order of business behind HAProxy. LangBot next, because the reset endpoint is unauthenticated and the remedy is a key rotation by hand that the upgrade will not perform for you. Then ESPnet and Nodemailer, both dependency audits rather than emergencies. Really Simple Security mostly needs confirmation that auto-update ran. snappy-java is availability-only and lands on the one decompression call that makes the caller size its own output buffer. Two records close the day: Flowise’s cross-workspace credential flaw, patched in July and given CVE IDs on Friday, six weeks later and by a third-party CNA rather than the vendor; and Internet Download Manager’s kernel driver, where a public proof of concept turns idmwfp.sys into an arbitrary registry write for any logged-in user and the vendor, by the CVE record’s account, has not responded.

    Still open at the end of the day. Two federal deadlines come due tomorrow: NVD’s records for ConnectWise ScreenConnect CVE-2026-84869 and GitLab CVE-2026-85706 both carry a cisaActionDue of 2026-09-14, Monday, September 14, 2026. Tonec has said nothing about the IDM driver, so there is no patch to wait for. snappy-java has shipped no release in more than a year. And Flowise is the day’s inverse case, worth keeping in view: the code was fixed on time, and the record took six weeks to say so.

  • ESPnet’s fix for its 8.8 checkpoint code execution flaw refuses to run on the PyTorch version its own metadata still allows

    ESPnet’s fix for its 8.8 checkpoint code execution flaw refuses to run on the PyTorch version its own metadata still allows

    The patched release swaps torch.load for a wrapper that raises an error on anything below PyTorch 2.6, while ESPnet’s own package metadata still declares torch>=2.3.1 — and on those older builds a dozen remaining load calls are unsafe by default.

    What happened

    NVD published CVE-2026-90777 at 12:17 p.m. UTC on Sunday, September 13, 2026. The record describes it in a sentence: “ESPnet before 202609 deserializes pretrained model checkpoints using torch.load with weights_only=False, allowing arbitrary code execution from attacker-supplied files.”

    ESPnet is an end-to-end speech processing toolkit — recognition, synthesis, enhancement, translation — and its normal workflow is to download somebody else’s pretrained checkpoint and run inference on it or fine-tune from it. That is the attack surface. The flaw is not reachable across the network against a running service; it is reachable the moment someone loads a model file from a hub.

    The scoring comes entirely from VulnCheck, the CNA here. NVD carries two metrics from [email protected]: a CVSS v3.1 base score of 8.8 High, vector CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H, marked Primary, and a CVSS v4.0 base score of 8.7 High, marked Secondary. The weakness is CWE-502, deserialization of untrusted data. There is no independent second assessment, and no source reports exploitation.

    The UI:R in that vector reads on paper like a mitigating factor. Here the required interaction is running a recipe or an inference script against a downloaded checkpoint — not something a careless user might be tricked into, but the toolkit’s entire purpose.

    GitHub advisory GHSA-64f6-3gqc-r926 was published on September 11, two days before the NVD record. It lists affected versions as 202511 and earlier, patched in 202609, and states the impact as “Arbitrary code execution as the user running the ESPnet training or inference process, triggered simply by loading an attacker-supplied pretrained model.” Credit goes to Jaime Ramírez, arexgodofwar, and Snakinya.

    The vulnerable line is exactly where the advisory says it is. At tag v.202511, line 99 of espnet2/torch_utils/load_pretrained_model.py reads:

    src_state = torch.load(path, map_location=map_location, weights_only=False)

    At tag v.202609, the same statement, now at line 101, reads:

    src_state = safe_torch_load(path, map_location=map_location)

    That release shipped on September 2, 2026 — eleven days before the CVE record and nine days before the GitHub advisory. Anyone reading the v.202609 release notes the day they came out would have found no reason to treat the upgrade as urgent. The notes do not contain the phrase “remote code execution,” and they name no CVE. The change appears as one line among behavior changes: “safe_torch_load no longer falls back to unsafe loading automatically; it must be opted into explicitly.” The only place the notes discuss security at any length is a section on continuous integration permissions, which observes that “the repository default turned out to be write on almost everything, on jobs that check out and run pull request code.”

    The fix has a precondition the package does not enforce

    We read the espnet-202609 wheel from PyPI — the artifact NVD marks unaffected. Two things in it do not line up.

    First, the new wrapper refuses to operate below PyTorch 2.6. espnet2/torch_utils/safe_torch_load.py checks the running version before doing anything else and raises:

    raise RuntimeError(
        "safe_torch_load requires PyTorch >= 2.6 for weights_only support. "
        f"Found torch.__version__={torch.__version__}, "
        "which is no longer supported by ESPnet."
    )

    Second, the same wheel’s metadata declares Requires-Dist: torch>=2.3.1. So the package asserts in its dependency list that PyTorch 2.3.1 is acceptable, and asserts in its security-critical code path that anything below 2.6 “is no longer supported by ESPnet.” A dependency resolver has no way to see the second statement. An environment that installs ESPnet 202609 alongside torch 2.4 or 2.5 satisfies the declared requirement completely, and every call into the fixed loading path raises a RuntimeError instead of loading a model.

    That is the better half of the outcome. The worse half is the paths the fix did not touch. Searching the shipped wheel for torch.load( calls outside the wrapper returns thirteen. One passes the unsafe flag explicitly — line 160 of espnet2/beats/generate_beats_checkpoint.py:

    pt_ckpt = torch.load(beats_pt_ckpt_path, map_location="cpu", weights_only=False)

    The other twelve pass no weights_only argument, so they inherit PyTorch’s default. Several sit in code a user reaches normally: espnet2/bin/enh_inference.py, espnet2/bin/enh_tse_inference.py, the AVHuBERT and HuBERT encoders, and the uASR task. PyTorch changed that default to weights_only=True in version 2.6. On 2.6 and later, those twelve calls are safe because of a decision made upstream in PyTorch, not because of anything in this fix. On 2.3.1 through 2.5 — versions ESPnet’s own metadata still permits — the default is weights_only=False, and those calls do precisely what CVE-2026-90777 describes.

    Put together: an installation that satisfies ESPnet’s stated dependencies but runs PyTorch below 2.6 gets a fixed path that throws and unfixed paths that execute attacker code. On that configuration, upgrading makes the software less usable without making it safer.

    Why it matters

    A machine learning checkpoint is a pickle, and a pickle is a program. The standard answers — weights_only=True, or the safetensors format — have existed for years. What CVE-2026-90777 documents is how long the old pattern survives inside a mature toolkit once it is load-bearing, and how partial the removal tends to be when it finally happens.

    The interesting failure here is not that ESPnet had an unsafe torch.load. It is the shape of the remediation. A version range is a binary instrument: NVD says versions below 202609 are affected and 202609 and above are not, and there is no field in that record that can express “unless your PyTorch is older than 2.6, in which case the fix does not run and a dozen other call sites are live.” Every scanner reading that record will report a machine running ESPnet 202609 on torch 2.5 as remediated. It is not, and the record is not wrong so much as incapable of saying so.

    This publication has covered several fixes in the past week that cover less than the flaw they close — a HAProxy patch that exists only as a commit, a GitLab release with no 18.x build carrying the fix. This one adds a variant: the fix exists, it is in a real release, and its effectiveness silently depends on the version of a transitive dependency the package does not pin. Anyone maintaining a requirements file has to know that to get the security benefit, and nothing in the advisory, the CVE record, or the release notes tells them.

    The nine-day gap between the fix shipping and the advisory naming it is not misconduct — coordinated disclosure often works this way, and shipping the fix first is the right order. But it left the September 2 release notes as the only public description of a remote code execution fix for nine days, and they described it as a behavior change to a helper function. Organizations that triage upgrades by reading release notes had nothing to go on.

    One detail deserves flagging as a thing to watch rather than a flaw. The wrapper still permits unsafe loading through three explicit opt-ins: allow_unsafe_fallback=True, the environment variable ESPNET_ALLOW_UNSAFE_TORCH_LOAD=1, or an interactive prompt. That is defensible, since legacy checkpoints have to remain loadable. The predictable failure mode is the environment variable landing in a Dockerfile to get one stubborn old checkpoint to load and staying there afterward, at which point the fix is off for every model that container ever touches.

    What to do

    Upgrade ESPnet to 202609 or later; the newest release on PyPI is 202609.post2, uploaded September 11, 2026.

    Then check the PyTorch version in the same environment, because the upgrade is incomplete without it:

    python -c "import espnet, torch; print(espnet.__version__, torch.__version__)"

    If torch is below 2.6, pin it up yourself — torch>=2.6 — because ESPnet’s metadata will not. Below that line you have neither a working safe loader nor safe defaults on the remaining call sites.

    Do not set ESPNET_ALLOW_UNSAFE_TORCH_LOAD=1 at the image or job level. If one legacy checkpoint genuinely needs the unsafe path, scope the variable to that single command.

    Treat espnet2/beats/generate_beats_checkpoint.py as a separate case. It still passes weights_only=False explicitly in the shipped 202609 wheel, so it is unsafe on any PyTorch version. Run it only against checkpoints you produced or otherwise trust.

    More broadly, treat third-party checkpoints as executables rather than data. Prefer safetensors where a model is published in that format, and do not fine-tune from a file pulled off a hub inside an environment that holds credentials you care about.

    Sourcing note

    Checked: the NVD record for CVE-2026-90777, including both CVSS metrics and their sources; GitHub Security Advisory GHSA-64f6-3gqc-r926; VulnCheck’s own advisory page; ESPnet’s source at tags v.202511 and v.202609, read directly from raw.githubusercontent.com; the espnet-202609 wheel downloaded from PyPI, including its METADATA and a full search for torch.load call sites; PyPI upload timestamps for every 2026 ESPnet release; and the GitHub release notes for v.202609.

    The affected-line quotations, the Requires-Dist line, the RuntimeError text, and the count of thirteen remaining torch.load call sites were read out of the published artifacts, because no advisory states them.

    cisa.gov returns 403 to automated fetching. We checked the cisagov/kev-data mirror instead: catalog version 2026.09.11, released September 11, 2026 at 7:32 p.m. UTC, 1,709 entries. CVE-2026-90777 is not in it, and no federal remediation deadline applies.

    Unresolved: whether ESPnet intends to raise its declared PyTorch floor to match what safe_torch_load requires, and whether the twelve bare torch.load calls are in scope for a follow-up. No source reports exploitation, and VulnCheck’s advisory makes no exploitation claim. The severity assessment is single-source: VulnCheck is the CNA and supplied both scores.