<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Michael Kantor</title>
    <description>The latest articles on DEV Community by Michael Kantor (@michael_kantor_c1f32eb919).</description>
    <link>https://dev.to/michael_kantor_c1f32eb919</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3717140%2F6d96c398-3f7d-43e3-a304-70f6415dfd4b.jpg</url>
      <title>DEV Community: Michael Kantor</title>
      <link>https://dev.to/michael_kantor_c1f32eb919</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/michael_kantor_c1f32eb919"/>
    <language>en</language>
    <item>
      <title>BREAKING: OpenShift console Devfile API lets anyone SSRF your cluster</title>
      <dc:creator>Michael Kantor</dc:creator>
      <pubDate>Fri, 18 Sep 2026 22:51:38 +0000</pubDate>
      <link>https://dev.to/hol/breaking-openshift-console-devfile-api-lets-anyone-ssrf-your-cluster-38n4</link>
      <guid>https://dev.to/hol/breaking-openshift-console-devfile-api-lets-anyone-ssrf-your-cluster-38n4</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://hol.org/blog/cve-2026-75885-openshift-console-unauth-devfile-ssrf" rel="noopener noreferrer"&gt;HOL&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Anyone who can reach your OpenShift console Route can POST to the Devfile parser with no login, and the console pod will fetch internal URLs and chew memory until it falls over.&lt;/strong&gt; Red Hat published &lt;strong&gt;CVE-2026-75885&lt;/strong&gt; today as Important (preliminary CVSS 9.3, CWE-918). The hole is unauthenticated access to &lt;code&gt;/api/devfile/&lt;/code&gt; and &lt;code&gt;/api/devfile/samples/&lt;/code&gt; in the OpenShift console (bridge). There is no RHSA and no Fixed In Version yet. Restrict who can reach the console Route now, and watch &lt;a href="https://access.redhat.com/security/cve/CVE-2026-75885" rel="noopener noreferrer"&gt;access.redhat.com for the errata&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is the operator write-up. The HOL Guard evidence pack for &lt;a href="https://hol.org/guard/security/cves/CVE-2026-75885?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=blog_distribution&amp;amp;utm_content=cve-2026-75885-openshift-console-unauth-devfile-ssrf" rel="noopener noreferrer"&gt;CVE-2026-75885&lt;/a&gt; is the source record. Do not open a second article for the authenticated Dev Console webhook SSRF sibling &lt;strong&gt;CVE-2026-50236&lt;/strong&gt;; that one needs a login. This one does not.&lt;/p&gt;

&lt;h2&gt;
  
  
  What breaks
&lt;/h2&gt;

&lt;p&gt;Red Hat’s advisory: unauthenticated access to the Devfile endpoints lets a remote attacker send crafted Devfile payloads. The console pod then makes requests to internal services (SSRF) and can reflect partial responses. Repeated large requests without a content length can drive unbounded memory growth and DoS.&lt;/p&gt;

&lt;p&gt;Bugzilla &lt;a href="https://bugzilla.redhat.com/show_bug.cgi?id=2517885" rel="noopener noreferrer"&gt;2517885&lt;/a&gt; (status NEW, Fixed In Version empty) is more specific. In &lt;code&gt;pkg/server/server.go&lt;/code&gt;, &lt;code&gt;/api/devfile/&lt;/code&gt; and &lt;code&gt;/api/devfile/samples/&lt;/code&gt; are registered with &lt;code&gt;handleFunc()&lt;/code&gt; and are &lt;em&gt;not&lt;/em&gt; wrapped in &lt;code&gt;authHandler&lt;/code&gt; / &lt;code&gt;authHandlerWithUser&lt;/code&gt; the way other &lt;code&gt;/api/*&lt;/code&gt; routes are. &lt;code&gt;DevfileHandler&lt;/code&gt; decodes an arbitrary JSON body and calls &lt;code&gt;ParseDevfileAndValidate&lt;/code&gt;. The Devfile library resolves &lt;code&gt;parent.uri&lt;/code&gt;, &lt;code&gt;Dockerfile.uri&lt;/code&gt;, and remote plugin references over HTTP from the console pod. There is no &lt;code&gt;MaxBytesReader&lt;/code&gt; / body size limit. Partial response bytes show up in the parser error string (partial-read SSRF). The reporter reproduced this on an OCP 5.0 nightly. Upstream tree: &lt;a href="https://github.com/openshift/console" rel="noopener noreferrer"&gt;openshift/console&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Red Hat scores it CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:L (9.3 Important), marks mitigation as not available under their Product Security criteria, and notes scores are preliminary. Impact in plain terms: an unauthenticated caller who can hit the console Route can use the console pod as a proxy into the cluster network and can DoS the console process with large bodies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who is not in scope
&lt;/h2&gt;

&lt;p&gt;Clusters where the OpenShift console Route is not reachable from the attacker (strict network policy, private console only, no public Route) remove the unauthenticated blast radius for this CVE, but that is exposure control, not a patch. Installs that do not run the OpenShift console / bridge are out of scope. Authenticated-only Dev Console webhook SSRF tracked as &lt;strong&gt;CVE-2026-50236&lt;/strong&gt; is a different bug with a login requirement; do not treat a fix for one as coverage for the other. Non-OpenShift Kubernetes dashboards (vanilla kube-dashboard, Rancher UI, etc.) are not this CVE.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to check
&lt;/h2&gt;

&lt;p&gt;From a host that can reach the console Route, without a session cookie or OAuth token, probe whether the Devfile endpoint accepts an unauthenticated POST (expect a parser error JSON, not a 401/403 redirect to login):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Replace CONSOLE with your console Route base URL (no trailing slash)&lt;/span&gt;
&lt;span class="c"&gt;# A 401/403/login redirect is healthy. A 200/4xx parser body without auth is the bad path.&lt;/span&gt;
curl &lt;span class="nt"&gt;-sk&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /tmp/devfile-probe.body &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s2"&gt;"HTTP %{http_code}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CONSOLE&lt;/span&gt;&lt;span class="s2"&gt;/api/devfile/"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"content":"schemaVersion: 2.2.0\nmetadata:\n  name: probe\n"}'&lt;/span&gt;

Also confirm which console image your cluster runs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the POST returns application JSON from the Devfile parser with no auth challenge, treat the Route as exposed to CVE-2026-75885 until Red Hat ships a console build that wraps those routes in auth and caps body size. Keep the probe payload tiny and stop after one request; do not load-test production.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to fix
&lt;/h2&gt;

&lt;p&gt;There is &lt;strong&gt;no public RHSA / Fixed In Version yet&lt;/strong&gt; (Bugzilla 2517885 still NEW with an empty Fixed In Version field as of this writing). Red Hat lists mitigation as not available under their criteria. Until errata lands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1) Restrict who can reach the console Route (NetworkPolicy / ingress / private API only)&lt;/span&gt;
&lt;span class="c"&gt;# 2) Watch for the RHSA on the CVE page, then upgrade the console operator / console image&lt;/span&gt;
&lt;span class="c"&gt;#    https://access.redhat.com/security/cve/CVE-2026-75885&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# After an RHSA ships, apply the errata the usual way for your OCP train, for example:&lt;/span&gt;
&lt;span class="c"&gt;#   oc adm upgrade --to=&amp;lt;errata-recommended-version&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;# or follow the RHSA package list for the console image digest.&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# Re-run the unauthenticated POST probe above and confirm you get auth failure, not parser output.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not invent a version number. When Red Hat publishes Fixed In Version / RHSA, upgrade that build and re-check the probe. Interim control is network exposure of the console Route, not a config flag named in the advisory.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this is not
&lt;/h2&gt;

&lt;p&gt;This is not remote code execution on the cluster and not a claim that every OpenShift install on the public internet is already owned. It is unauthenticated SSRF plus resource-exhaustion DoS through two Devfile API routes on the console, with Scope Changed and Confidentiality High on Red Hat’s preliminary 9.3. It is not the authenticated Dev Console webhook SSRF (CVE-2026-50236). It is not “wait for NVD analysis before acting”: if your console Route is reachable, shrink exposure today and watch for the RHSA.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://access.redhat.com/security/cve/CVE-2026-75885" rel="noopener noreferrer"&gt;Red Hat CVE-2026-75885&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://bugzilla.redhat.com/show_bug.cgi?id=2517885" rel="noopener noreferrer"&gt;Bugzilla 2517885&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.cve.org/CVERecord?id=CVE-2026-75885" rel="noopener noreferrer"&gt;CVE-2026-75885 (CVE Program)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://nvd.nist.gov/vuln/detail/CVE-2026-75885" rel="noopener noreferrer"&gt;NVD CVE-2026-75885&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/openshift/console" rel="noopener noreferrer"&gt;openshift/console (upstream)&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cve</category>
      <category>openshift</category>
      <category>ssrf</category>
      <category>dos</category>
    </item>
    <item>
      <title>BREAKING: WordPress comment XSS lets strangers plant script (7.1.1)</title>
      <dc:creator>Michael Kantor</dc:creator>
      <pubDate>Fri, 18 Sep 2026 06:21:30 +0000</pubDate>
      <link>https://dev.to/hol/breaking-wordpress-comment-xss-lets-strangers-plant-script-711-1678</link>
      <guid>https://dev.to/hol/breaking-wordpress-comment-xss-lets-strangers-plant-script-711-1678</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://hol.org/blog/cve-2026-93485-wordpress-711-unauth-comment-xss" rel="noopener noreferrer"&gt;HOL&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;An unauthenticated visitor can leave stored script in WordPress through comment formatting, and WordPress just shipped 7.1.1 to stop that path.&lt;/strong&gt; The CVE List entry is &lt;strong&gt;CVE-2026-93485&lt;/strong&gt; (Patchstack): DOM-based / stored XSS in core paragraph formatting. WordPress.org’s own security notes say the issue is unauthenticated stored XSS via paragraph formatting, &lt;em&gt;subject to comment approval&lt;/em&gt;. The same short-cycle release also closes ten other security bugs. Treat 7.1.1 as an emergency upgrade for any site still on 7.1 or older supported branches.&lt;/p&gt;

&lt;p&gt;This is the operator write-up for the WordPress 7.1.1 security train. The HOL Guard evidence pack for &lt;a href="https://hol.org/guard/security/cves/CVE-2026-93485-wordpress-core-71-unauth-cross-site-scripting-xss?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=blog_distribution&amp;amp;utm_content=cve-2026-93485-wordpress-711-unauth-comment-xss" rel="noopener noreferrer"&gt;CVE-2026-93485&lt;/a&gt; is the source record. Do not open a second blog post for the other fixes in this same upgrade.&lt;/p&gt;

&lt;h2&gt;
  
  
  What breaks
&lt;/h2&gt;

&lt;p&gt;WordPress published &lt;a href="https://wordpress.org/news/2026/09/wordpress-7-1-1-maintenance-and-security-release/" rel="noopener noreferrer"&gt;WordPress 7.1.1 Maintenance and Security Release&lt;/a&gt; (dated 2026-09-17 on the news post; CVE-2026-93485 published 2026-09-18). Official wording credits Rafie Muhammad (Awesome Motive) for stored XSS in &lt;code&gt;wpautop()&lt;/code&gt; that lets an unauthenticated visitor inject script, subject to comment approval. Patchstack’s CVE text adds that a default install can reproduce the unauthenticated stored XSS path: comment moderation is off by default, and the “must have a previously approved comment” gate can be bypassed.&lt;/p&gt;

&lt;p&gt;Affected trains named in the CVE: WordPress 7.1 before 7.1.1, plus older lines through the usual security-backport range (7.0.x through 4.7.x as listed in the CVE). Fixed for the current line: &lt;strong&gt;7.1.1&lt;/strong&gt;. Patchstack marks the issue CVSS 7.1 (High) with unauthenticated required privilege and user interaction required for full impact.&lt;/p&gt;

&lt;p&gt;CVE-2026-93485 is not the only reason to move. The same 7.1.1 release lists &lt;strong&gt;11 security fixes&lt;/strong&gt;, including (paraphrased from WordPress.org, not separate CVE IDs unless you have them):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Crafted URL that can install and preview an inactive theme from WordPress.org&lt;/li&gt;
&lt;li&gt;  Stored XSS in some themes that support custom headers&lt;/li&gt;
&lt;li&gt;  HTML API &lt;code&gt;set_modifiable_text()&lt;/code&gt; comment break-out&lt;/li&gt;
&lt;li&gt;  Contributor+ arbitrary post overwrite&lt;/li&gt;
&lt;li&gt;  Authenticated path traversal in the REST templates controller&lt;/li&gt;
&lt;li&gt;  XML-RPC path that can publish &lt;code&gt;customize_changeset&lt;/code&gt; posts bypassing &lt;code&gt;edit_css&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Site Administrator network-activating a network-only plugin (multisite)&lt;/li&gt;
&lt;li&gt;  Missing &lt;code&gt;read_post&lt;/code&gt; check leaking a private parent-post title&lt;/li&gt;
&lt;li&gt;  Contributor+ draft/pending post slug disclosure&lt;/li&gt;
&lt;li&gt;  Any authenticated user reparenting comments (including notes)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;WordPress.org recommends updating immediately because this is a security release. Automatic background updates will pick it up where enabled.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who is not in scope
&lt;/h2&gt;

&lt;p&gt;Sites already running &lt;strong&gt;WordPress 7.1.1&lt;/strong&gt; (or the matching security backport for your branch once it lands) are outside CVE-2026-93485. Static HTML, headless frontends that never render WordPress comments, and installs with comments fully closed remove the comment-injection path for this CVE, but they are not a substitute for the 7.1.1 binary if you still run core PHP for admin, REST, XML-RPC, or themes. Multisite-only items in the 11-fix list do not apply to single-site installs. Non-WordPress CMSes are out of scope.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to check
&lt;/h2&gt;

&lt;p&gt;On every WordPress host (and every container image that embeds core):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# WP-CLI&lt;/span&gt;
wp core version
wp core check-update

or from PHP &lt;span class="k"&gt;in &lt;/span&gt;the site root
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Confirm the printed version is &lt;strong&gt;7.1.1&lt;/strong&gt; or newer on the 7.1 line (or the patched build for your older branch after backports ship). In wp-admin: &lt;strong&gt;Dashboard → Updates&lt;/strong&gt; should show 7.1.1 available or already installed. Also note whether comments are open on public posts (&lt;code&gt;wp option get default_comment_status&lt;/code&gt;) and whether moderation is required. Those settings change how easy the CVE-2026-93485 path is to hit; they do not replace the core upgrade.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to fix
&lt;/h2&gt;

&lt;p&gt;Upgrade WordPress to &lt;strong&gt;7.1.1&lt;/strong&gt; (or the security build for your supported branch) and verify the version string afterward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# WP-CLI (preferred)&lt;/span&gt;
wp core update &lt;span class="nt"&gt;--version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;7.1.1
wp core update-db
wp core version

or Dashboard → Updates → Update Now
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you run multiple sites from one image, rebuild and redeploy the image rather than patching only one container. After upgrade, spot-check a public post with comments: submit a benign test comment and confirm it still behaves under your moderation policy. Review recent pending/approved comments for unexpected markup while you are there. WordPress notes security backports for older branches (through 4.7) are in progress; do not wait on a backport if you can move the current line to 7.1.1 now.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this is not
&lt;/h2&gt;

&lt;p&gt;This is not remote code execution and not an unauthenticated admin takeover. CVE-2026-93485 is stored / DOM XSS: an attacker plants script that runs in a visitor’s or moderator’s browser when the poisoned content is viewed. WordPress.org’s advisory ties the unauthenticated path to comment approval. It is not “every WordPress site is already owned,” and it is not limited to one obscure plugin. It is core, same-week, with an official “update immediately” security release that also closes ten other issues. Upgrade first; argue severity later.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://wordpress.org/news/2026/09/wordpress-7-1-1-maintenance-and-security-release/" rel="noopener noreferrer"&gt;WordPress 7.1.1 Maintenance and Security Release&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://wordpress.org/documentation/wordpress-version/version-7-1-1/" rel="noopener noreferrer"&gt;WordPress 7.1.1 HelpHub / version notes&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.cve.org/CVERecord?id=CVE-2026-93485" rel="noopener noreferrer"&gt;CVE-2026-93485 (CVE Program)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://patchstack.com/database/wordpress/wordpress/wordpress/vulnerability/wordpress-wordpress-wordpress-7-1-cross-site-scripting-xss-vulnerability" rel="noopener noreferrer"&gt;Patchstack entry for CVE-2026-93485&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://hol.org/guard/security/cves/CVE-2026-93485-wordpress-core-71-unauth-cross-site-scripting-xss?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=blog_distribution&amp;amp;utm_content=cve-2026-93485-wordpress-711-unauth-comment-xss" rel="noopener noreferrer"&gt;HOL Guard pack CVE-2026-93485&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cve</category>
      <category>wordpress</category>
      <category>xss</category>
      <category>securityrelease</category>
    </item>
    <item>
      <title>Aborted multer uploads still fill the disk after the 5038 fix</title>
      <dc:creator>Michael Kantor</dc:creator>
      <pubDate>Wed, 16 Sep 2026 13:35:27 +0000</pubDate>
      <link>https://dev.to/hol/aborted-multer-uploads-still-fill-the-disk-after-the-5038-fix-32ol</link>
      <guid>https://dev.to/hol/aborted-multer-uploads-still-fill-the-disk-after-the-5038-fix-32ol</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://hol.org/blog/cve-2026-88932-multer-aborted-upload-orphaned-disk-dos" rel="noopener noreferrer"&gt;HOL&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Abort a multer disk upload before the storage engine names the file, and the complete write can still land as an orphan.&lt;/strong&gt; The June 2026 fix for CVE-2026-5038 cleaned uploads that already had a destination path. It did not catch the brief window where the request dies before &lt;code&gt;diskStorage&lt;/code&gt; assigns that path. Late-completing writes leave finished files behind. An unauthenticated client that can open multipart uploads can accumulate those orphans until the upload directory or system temp fills. If you upgraded to &lt;code&gt;2.2.0&lt;/code&gt; or &lt;code&gt;2.3.0&lt;/code&gt; for 5038, you are still exposed.&lt;/p&gt;

&lt;p&gt;Upgrade to &lt;code&gt;multer@2.4.0&lt;/code&gt;. That release is the incomplete-fix follow-through for the same orphaned-disk class.&lt;/p&gt;

&lt;h2&gt;
  
  
  What breaks
&lt;/h2&gt;

&lt;p&gt;GitHub advisory &lt;a href="https://github.com/expressjs/multer/security/advisories/GHSA-3pph-fpjx-jg34" rel="noopener noreferrer"&gt;GHSA-3pph-fpjx-jg34&lt;/a&gt; / CVE-2026-88932 rates this Moderate (CVSS 5.3, AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L; CWE-400, CWE-459). Impact is availability only, and only for &lt;code&gt;diskStorage&lt;/code&gt;. npm published &lt;code&gt;2.4.0&lt;/code&gt; the same day as the advisory (2026-09-14); the GitHub release tag landed minutes earlier. Weekly downloads for &lt;code&gt;multer&lt;/code&gt; sit around 15.6 million. About 52% of that traffic (~8.0M) was still on &lt;code&gt;2.2.x&lt;/code&gt;/&lt;code&gt;2.3.x&lt;/code&gt; last week (&lt;code&gt;2.2.0&lt;/code&gt; ~4.77M, &lt;code&gt;2.3.0&lt;/code&gt; ~3.31M), which is exactly the train people moved onto after 5038.&lt;/p&gt;

&lt;p&gt;The 2.4.0 patch does what the GHSA one-liner does not spell out. Commit &lt;a href="https://github.com/expressjs/multer/commit/53337f9713619ef3381ee6b4e541f926dbaac305" rel="noopener noreferrer"&gt;53337f97&lt;/a&gt; ("fix: remove late-completing uploads aborted before the engine names them") tracks &lt;code&gt;abortCleanupDone&lt;/code&gt; and &lt;code&gt;abortRemovedFiles&lt;/code&gt; in &lt;code&gt;lib/make-middleware.js&lt;/code&gt;. If the storage engine finishes after abort cleanup already ran, middleware calls &lt;code&gt;storage._removeFile&lt;/code&gt; directly instead of leaving the orphan. The regression test is &lt;code&gt;test/orphan-before-path-assignment.js&lt;/code&gt;. Async &lt;code&gt;destination&lt;/code&gt; / &lt;code&gt;filename&lt;/code&gt; callbacks widen the race: more time between abort and path assignment means more room for a late complete write.&lt;/p&gt;

&lt;p&gt;Affected: npm &lt;code&gt;multer&lt;/code&gt; &lt;code&gt;&amp;gt;=2.2.0 &amp;lt;2.4.0&lt;/code&gt;. Fixed: &lt;code&gt;2.4.0&lt;/code&gt;. The earlier advisory is &lt;a href="https://github.com/expressjs/multer/security/advisories/GHSA-3p4h-7m6x-2hcm" rel="noopener noreferrer"&gt;GHSA-3p4h-7m6x-2hcm&lt;/a&gt; / CVE-2026-5038.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who is not in scope
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  Apps that never use &lt;code&gt;multer.diskStorage&lt;/code&gt; (for example &lt;code&gt;memoryStorage&lt;/code&gt; only).&lt;/li&gt;
&lt;li&gt;  Already-patched installs on &lt;code&gt;2.4.0&lt;/code&gt; or later.&lt;/li&gt;
&lt;li&gt;  multer v1.x (~19% of weekly downloads last week). That line is outside the affected range for &lt;em&gt;this&lt;/em&gt; CVE; do not treat 88932 as a v1 upgrade mandate.&lt;/li&gt;
&lt;li&gt;  Uploads that never abort before the engine assigns a path (the 5038 cleanup path already covered those).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to check
&lt;/h2&gt;

&lt;p&gt;From the app root:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;npm ls multer
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Any resolved version in &lt;code&gt;2.2.0&lt;/code&gt; through &lt;code&gt;2.3.x&lt;/code&gt; is vulnerable to this follow-on. In lockfiles, confirm the resolved version string, including transitive copies from Express scaffolds and upload helpers. If you pin an override for 5038 at &lt;code&gt;2.2.0&lt;/code&gt; or &lt;code&gt;2.3.0&lt;/code&gt;, bump that pin.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to fix
&lt;/h2&gt;

&lt;p&gt;Upgrade multer to the patched release.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;npm install multer@2.4.0
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pin or override transitive copies so every resolved path is &lt;code&gt;2.4.0&lt;/code&gt; or newer, then restart the process. After deploy, check the configured upload directory and &lt;code&gt;os.tmpdir()&lt;/code&gt; for leftover orphaned files from abort traffic; the patch stops new orphans, it does not vacuum old ones.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this is not
&lt;/h2&gt;

&lt;p&gt;This is not remote code execution, not path traversal outside the configured destination, and not a &lt;code&gt;memoryStorage&lt;/code&gt; bug. A remote client that can start multipart uploads and abort early can drive disk exhaustion on the upload path. Damage stops at availability.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://github.com/expressjs/multer/security/advisories/GHSA-3pph-fpjx-jg34" rel="noopener noreferrer"&gt;GHSA-3pph-fpjx-jg34&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.cve.org/CVERecord?id=CVE-2026-88932" rel="noopener noreferrer"&gt;CVE-2026-88932&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/expressjs/multer/commit/53337f9713619ef3381ee6b4e541f926dbaac305" rel="noopener noreferrer"&gt;multer 2.4.0 fix commit 53337f97&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/expressjs/multer/security/advisories/GHSA-3p4h-7m6x-2hcm" rel="noopener noreferrer"&gt;Prior incomplete fix GHSA-3p4h-7m6x-2hcm / CVE-2026-5038&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://hol.org/guard/security/cves/CVE-2026-88932-multer-vulnerable-to-denial-of-service-via?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=blog_distribution&amp;amp;utm_content=cve-2026-88932-multer-aborted-upload-orphaned-disk-dos" rel="noopener noreferrer"&gt;HOL Guard evidence pack for CVE-2026-88932&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cve</category>
      <category>multer</category>
      <category>npm</category>
      <category>dos</category>
    </item>
    <item>
      <title>BREAKING: Unbound DNSKEY digest overflow can RCE your resolver (1.26.1)</title>
      <dc:creator>Michael Kantor</dc:creator>
      <pubDate>Wed, 16 Sep 2026 09:14:41 +0000</pubDate>
      <link>https://dev.to/hol/breaking-unbound-dnskey-digest-overflow-can-rce-your-resolver-1261-42gi</link>
      <guid>https://dev.to/hol/breaking-unbound-dnskey-digest-overflow-can-rce-your-resolver-1261-42gi</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://hol.org/blog/cve-2026-81642-unbound-dnskey-digest-rce" rel="noopener noreferrer"&gt;HOL&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your recursive DNS resolver can take attacker-controlled data from a malicious zone and overflow a digest buffer while validating DNSKEY records.&lt;/strong&gt; NLnet Labs shipped Unbound 1.26.1 today (2026-09-16) with a same-day CVE batch. The lead issue is &lt;strong&gt;CVE-2026-81642&lt;/strong&gt;: a heap overflow in the DNSSEC validator when digesting DNSKEYs, with possible remote code execution through attacker-controlled data. An adversary who controls a malicious zone only needs a vulnerable Unbound to query it.&lt;/p&gt;

&lt;p&gt;This is the operator write-up for the 1.26.1 upgrade train. The HOL Guard evidence pack for &lt;a href="https://hol.org/guard/security/cves/CVE-2026-81642-heap-buffer-overflow-and-possible-remote-code?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=blog_distribution&amp;amp;utm_content=cve-2026-81642-unbound-dnskey-digest-rce" rel="noopener noreferrer"&gt;CVE-2026-81642&lt;/a&gt; is the source record. Sibling packs for the same release sit under Guard as well; do not open a second blog post for this train.&lt;/p&gt;

&lt;h2&gt;
  
  
  What breaks
&lt;/h2&gt;

&lt;p&gt;Vendor advisory for CVE-2026-81642: a DNSKEY whose owner name uses a compression pointer into its own RDATA can overflow the digest buffer. Remote code execution is possible through attacker-controlled data. Unbound 1.26.1 checks buffer capacity after decompression and before writing.&lt;/p&gt;

&lt;p&gt;That bug is not alone. The same 1.26.1 tarball also closes other same-day Unbound CVEs that share the upgrade:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;CVE-2026-82717&lt;/strong&gt;: CNAME synthesis that rewrites a max TTL in the packet buffer, plus a bad compression pointer, can progressively corrupt heap memory. Under some systems and compilation options that can become RCE. Disclosed by Ben Morris (Anthropic).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;CVE-2026-81634&lt;/strong&gt;: a 255-length query name with a large TCP response can heap-overflow during RRSet canonicalisation before DNSSEC validation. Triggerable from a malicious name server or a tampered response.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;CVE-2026-82720&lt;/strong&gt;: use-after-free on DoH stream cleanup when Unbound is built &lt;code&gt;--with-libnghttp2&lt;/code&gt;. Failure paths (RPZ drop, jostle under load) can free a session while other streams remain. Reads are not attacker-controlled; a hardened allocator can turn this into DoS. Affects 1.12.0 through 1.26.0 with DoH.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;CVE-2026-85501&lt;/strong&gt;: ReTrap algorithmic DNSSEC complexity attacks (TagTrap, DelegationTrap, NsecTrap, AdditionalTrap). 1.26.1 adds match/operation/NSEC caps and defaults &lt;code&gt;val-clean-additional&lt;/code&gt; to off.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;CVE-2026-80225&lt;/strong&gt;: unbounded consecutive TCP/DoT reads let a client monopolize one worker's event loop with distinct uncached names.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;CVE-2026-78227&lt;/strong&gt;: DoQ use-after-free when built &lt;code&gt;--with-libngtcp2&lt;/code&gt; (1.22.0-1.26.0): RESET_STREAM frees the stream output buffer while ngtcp2 still holds retransmission pointers.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;CVE-2026-77955&lt;/strong&gt;: ZONEMD zones below a trust anchor (&lt;code&gt;zonemd-check: yes&lt;/code&gt;) can briefly serve or write tampered contents before verification finishes (1.13.2-1.26.0).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;CVE-2026-77860&lt;/strong&gt;: &lt;code&gt;serve-expired&lt;/code&gt; double-decrements the per-client &lt;code&gt;wait-limit&lt;/code&gt;, weakening the DNSBomb countermeasure from CVE-2024-33655 (1.20.0-1.26.0).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Affected line for the RCE-class DNSKEY and CNAME bugs: Unbound up to and including &lt;strong&gt;1.26.0&lt;/strong&gt;. Fixed line: &lt;strong&gt;Unbound 1.26.1&lt;/strong&gt; (&lt;a href="https://nlnetlabs.nl/downloads/unbound/unbound-1.26.1.tar.gz" rel="noopener noreferrer"&gt;unbound-1.26.1.tar.gz&lt;/a&gt;). Distro packages will lag; treat anything still reporting 1.26.0 or older as in the blast radius until you confirm the patch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who is not in scope
&lt;/h2&gt;

&lt;p&gt;Resolvers that are not Unbound (BIND, Knot Resolver, PowerDNS Recursor, systemd-resolved, cloud recursive anycast) are outside this advisory set. Unbound already on 1.26.1 is outside. CVE-2026-82720 does not apply if you never built with &lt;code&gt;--with-libnghttp2&lt;/code&gt; / DoH. CVE-2026-78227 does not apply without &lt;code&gt;--with-libngtcp2&lt;/code&gt; / DoQ. CVE-2026-77955 only hits operators who enable &lt;code&gt;zonemd-check: yes&lt;/code&gt; on zones below a trust anchor. CVE-2026-77860 only bites when &lt;code&gt;serve-expired&lt;/code&gt; is on. Stub resolvers and authoritative-only Unbound deployments that never recurse into attacker zones still need the binary upgrade for the shared code paths, but the practical DNSKEY/CNAME RCE story is recursive validation against a hostile zone.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to check
&lt;/h2&gt;

&lt;p&gt;On every Unbound host (and every container image that embeds it):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;unbound &lt;span class="nt"&gt;-V&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; 5
&lt;span class="c"&gt;# or&lt;/span&gt;
unbound &lt;span class="nt"&gt;-V&lt;/span&gt; 2&amp;gt;&amp;amp;1 | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s1"&gt;'Version|linked libs|libnghttp2|ngtcp2'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Confirm the printed Version is &lt;strong&gt;1.26.1&lt;/strong&gt; or newer. Also note whether the build line mentions libnghttp2 or ngtcp2; those flags decide whether 82720 / 78227 were reachable on that binary. Package managers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dpkg &lt;span class="nt"&gt;-l&lt;/span&gt; unbound 2&amp;gt;/dev/null | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'/^ii/ {print $2,$3}'&lt;/span&gt;
rpm &lt;span class="nt"&gt;-q&lt;/span&gt; unbound 2&amp;gt;/dev/null
&lt;span class="c"&gt;# FreeBSD / ports style&lt;/span&gt;
pkg info unbound 2&amp;gt;/dev/null | &lt;span class="nb"&gt;head&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your fleet runs Unbound behind Ansible, Puppet, or a distro mirror, inventory the running binary version, not just the package name on the mirror metadata. A host still answering on 1.26.0 after the mirror shows 1.26.1 is still vulnerable.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to fix
&lt;/h2&gt;

&lt;p&gt;Upgrade Unbound to &lt;strong&gt;1.26.1&lt;/strong&gt; and restart the service. Prefer the vendor tarball or your distro's patched package once it lands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# source build (vendor)&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; &lt;span class="nt"&gt;-O&lt;/span&gt; https://nlnetlabs.nl/downloads/unbound/unbound-1.26.1.tar.gz
&lt;span class="nb"&gt;tar &lt;/span&gt;xf unbound-1.26.1.tar.gz &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;unbound-1.26.1
./configure &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; make &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;make &lt;span class="nb"&gt;install
sudo &lt;/span&gt;systemctl restart unbound
unbound &lt;span class="nt"&gt;-V&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For Unbound 1.26.0 source trees that cannot jump packages yet, NLnet Labs published per-CVE patches (full and minimal) next to each advisory on &lt;a href="https://www.nlnetlabs.nl/downloads/unbound/" rel="noopener noreferrer"&gt;nlnetlabs.nl/downloads/unbound/&lt;/a&gt;. Apply with &lt;code&gt;patch -p1&lt;/code&gt; then &lt;code&gt;make install&lt;/code&gt;. Operators should still prefer the full 1.26.1 release so every sibling in this batch lands together.&lt;/p&gt;

&lt;p&gt;After upgrade, re-check &lt;code&gt;unbound -V&lt;/code&gt;, confirm workers are on the new binary (&lt;code&gt;systemctl status unbound&lt;/code&gt; / process start time), and watch recursion logs for unusual DNSSEC failures from zones you do not own. If you expose DoH or DoQ, treat those listeners as in-scope until the build flags and version both clear.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this is not
&lt;/h2&gt;

&lt;p&gt;This is not a confirmed in-the-wild worm as of the vendor notes we used (the advisories do not claim active exploitation). It is not "any DNS software." It is not automatic RCE on every Unbound install: CVE-2026-81642 and CVE-2026-82717 need a path where Unbound digests or synthesizes against attacker-influenced zone data, and 82717's RCE path is layout- and build-dependent. DoH/DoQ UAFs need those features compiled in. ReTrap and the TCP/DoT read starvation bugs are availability and resource-abuse stories, not the same as the DNSKEY digest RCE. Still: Unbound is widely deployed recursive DNS. Same-day vendor RCE language on the resolver that answers for your network is enough to treat 1.26.1 as an emergency upgrade.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://www.nlnetlabs.nl/downloads/unbound/CVE-2026-81642.txt" rel="noopener noreferrer"&gt;NLnet Labs advisory CVE-2026-81642&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.nlnetlabs.nl/downloads/unbound/CVE-2026-82717.txt" rel="noopener noreferrer"&gt;NLnet Labs advisory CVE-2026-82717&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.nlnetlabs.nl/downloads/unbound/CVE-2026-82720.txt" rel="noopener noreferrer"&gt;NLnet Labs advisory CVE-2026-82720&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.nlnetlabs.nl/downloads/unbound/CVE-2026-85501.txt" rel="noopener noreferrer"&gt;NLnet Labs advisory CVE-2026-85501&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.nlnetlabs.nl/downloads/unbound/CVE-2026-81634.txt" rel="noopener noreferrer"&gt;NLnet Labs advisory CVE-2026-81634&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.nlnetlabs.nl/downloads/unbound/CVE-2026-80225.txt" rel="noopener noreferrer"&gt;NLnet Labs advisory CVE-2026-80225&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.nlnetlabs.nl/downloads/unbound/CVE-2026-78227.txt" rel="noopener noreferrer"&gt;NLnet Labs advisory CVE-2026-78227&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.nlnetlabs.nl/downloads/unbound/CVE-2026-77955.txt" rel="noopener noreferrer"&gt;NLnet Labs advisory CVE-2026-77955&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.nlnetlabs.nl/downloads/unbound/CVE-2026-77860.txt" rel="noopener noreferrer"&gt;NLnet Labs advisory CVE-2026-77860&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://nlnetlabs.nl/downloads/unbound/unbound-1.26.1.tar.gz" rel="noopener noreferrer"&gt;Unbound 1.26.1 source tarball&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://hol.org/guard/security/cves/CVE-2026-81642-heap-buffer-overflow-and-possible-remote-code?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=blog_distribution&amp;amp;utm_content=cve-2026-81642-unbound-dnskey-digest-rce" rel="noopener noreferrer"&gt;HOL Guard pack CVE-2026-81642&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cve</category>
      <category>unbound</category>
      <category>dns</category>
      <category>dnssec</category>
    </item>
    <item>
      <title>Hidden command in Claude Code: base64 piped to sh</title>
      <dc:creator>Michael Kantor</dc:creator>
      <pubDate>Tue, 15 Sep 2026 13:21:55 +0000</pubDate>
      <link>https://dev.to/hol/hidden-command-in-claude-code-base64-piped-to-sh-2d0f</link>
      <guid>https://dev.to/hol/hidden-command-in-claude-code-base64-piped-to-sh-2d0f</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://hol.org/blog/guard-protects-encoded-execution-pipe" rel="noopener noreferrer"&gt;HOL&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You were in Claude Code. The chat line looked short. Under it the agent packed a hidden command in base64 and tried to pipe the decode straight into &lt;code&gt;sh&lt;/code&gt;. If that finishes, whatever was inside is already running on your laptop. You never saw the real program as a normal argv list.&lt;/p&gt;

&lt;p&gt;HOL Guard froze that line before the decode hit a shell. Two buttons on screen: &lt;strong&gt;Allow just this once&lt;/strong&gt;, or &lt;strong&gt;Keep blocked&lt;/strong&gt;. Until you tap Allow, the packed command has not started.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzzl55hfp75gt2n8vlsyu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzzl55hfp75gt2n8vlsyu.png" alt="HOL Guard Inbox: PAUSED ACTION Needs review on a hidden base64 decode pipe to sh, Allow just this once and Keep blocked" width="800" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Local Inbox review for a paused Claude Code command. Queue shows the short decode line; the card is PAUSED ACTION / Needs review with Allow just this once and Keep blocked.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffd5fa81w0ld3zhdrd8al.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffd5fa81w0ld3zhdrd8al.png" alt="Close-up of Allow just this once (green) and Keep blocked buttons on HOL Guard review card" width="684" height="194"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Button labels on the live review card: Allow just this once, Keep blocked. Scope defaults to a one-time allow for this exact action.&lt;/p&gt;

&lt;p&gt;Keep blocked leaves the action stopped. The receipt stays on your machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a short chat line still hurts
&lt;/h2&gt;

&lt;p&gt;Most shell policy starts with command words you can read. A decode-then-run chain breaks that habit. Outer tokens look like a decoder. The program that matters appears only after decode. Review exists so a human sees the shape before a shell gets that output.&lt;/p&gt;

&lt;p&gt;Sibling Extensions still matter. If the decoded content would curl credentials, that is &lt;code&gt;command.data-protection&lt;/code&gt;. If the agent tries to clear the pause itself, that is &lt;code&gt;command.guard-self-protection&lt;/code&gt;. This Extension only claims decode or decrypt, then immediate execute.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Guard maps
&lt;/h2&gt;

&lt;p&gt;Built-in &lt;a href="https://hol.org/guard/extensions/command.encoded-execution?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=blog_distribution&amp;amp;utm_content=guard-protects-encoded-execution-pipe" rel="noopener noreferrer"&gt;Encoded execution protection&lt;/a&gt; (&lt;code&gt;command.encoded-execution&lt;/code&gt;, v1.0.0, high). Catalog default: review. One operation: &lt;strong&gt;Encoded execution&lt;/strong&gt; (&lt;code&gt;command.encoded-execution.decode-and-execute&lt;/code&gt;). Identifies decode or decrypt chains that immediately execute their output.&lt;/p&gt;

&lt;p&gt;Catalog shape (reviewed by default): &lt;code&gt;echo &amp;lt;base64&amp;gt; | base64 --decode | sh&lt;/code&gt;. Copy the live example from the directory page. Do not invent a payload for this blog paste path.&lt;/p&gt;

&lt;p&gt;A workspace can tighten to block or loosen the floor unless a managed-restrictive Control Set pins the Extension. Catalog default is not your fleet policy.&lt;/p&gt;

&lt;p&gt;On Protect / Extensions, leave posture at Protected unless you have a deliberate reason to Watch. Watch will not stop the chain. Extra careful raises friction when your team wants more pauses around nearby shapes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Out of scope
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;command.encoded-execution&lt;/code&gt; does not cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Decoding content to a file and stopping there, with no execute step in the same reviewed chain.&lt;/li&gt;
&lt;li&gt;  Credential-file send or local upload via curl: &lt;code&gt;command.data-protection&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  An agent calling &lt;code&gt;hol-guard approvals approve&lt;/code&gt; on itself: &lt;code&gt;command.guard-self-protection&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Package installs and one-shot runners (&lt;code&gt;npx&lt;/code&gt;, &lt;code&gt;npm&lt;/code&gt;): Package Firewall Extensions.&lt;/li&gt;
&lt;li&gt;  Obfuscation that never hits a reviewed decode-and-execute op.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  One check that does not run the pipe
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;command test&lt;/code&gt; and &lt;code&gt;command explain&lt;/code&gt; do not execute the command, create an approval, or write a receipt.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hol-guard command test '&amp;lt;paste catalog decode-and-execute example&amp;gt;'
hol-guard command explain '&amp;lt;paste catalog decode-and-execute example&amp;gt;'
hol-guard command controls show command.encoded-execution
hol-guard command extensions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the catalog example from the directory page. Do not paste a live decode-pipe as a copy-paste exploit on this page. After an upgrade, run the test before you trust muscle memory. If test says unrecognized, confirm the Extension is current and posture is not Watch.&lt;/p&gt;

&lt;h2&gt;
  
  
  After Inbox lights up
&lt;/h2&gt;

&lt;p&gt;This pause is for decode-or-decrypt then immediate execute. Ordinary base64 that never runs a shell is not in scope.&lt;/p&gt;

&lt;p&gt;Change the permission in Protect / Extensions or via CLI. For a team floor that local auto-approve cannot weaken, pin a managed-restrictive Control Set on this Extension's permission ID.&lt;/p&gt;

&lt;p&gt;If you meant the decode-and-execute, choose Allow just this once after you know what the decoded stream becomes. If you did not, Keep blocked and find which prompt or tool suggested the chain. Receipt stays local. Cloud sync is optional and does not carry the raw command.&lt;/p&gt;

&lt;p&gt;Background: &lt;a href="https://hol.org/blog/hol-guard-3-0-extension-first-managed-controls?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=blog_distribution&amp;amp;utm_content=guard-protects-encoded-execution-pipe" rel="noopener noreferrer"&gt;HOL Guard 3.0&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>holguard</category>
      <category>guardextensions</category>
      <category>encodedexecution</category>
      <category>agentsecurity</category>
    </item>
    <item>
      <title>Keep a Codex Task on Track Through Compaction with Context Guard</title>
      <dc:creator>Michael Kantor</dc:creator>
      <pubDate>Sat, 12 Sep 2026 18:41:27 +0000</pubDate>
      <link>https://dev.to/hol/keep-a-codex-task-on-track-through-compaction-with-context-guard-3ihh</link>
      <guid>https://dev.to/hol/keep-a-codex-task-on-track-through-compaction-with-context-guard-3ihh</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://hol.org/blog/context-guard-codex-compaction-evidence-workflow" rel="noopener noreferrer"&gt;HOL&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A long Codex task can involve research, edits, tests, and several changes of direction. When the conversation is compacted, you still need the original constraints to apply to the result. You also need to know which requirements have actually been checked.&lt;/p&gt;

&lt;p&gt;Context Guard keeps a private checklist of requirements and verification evidence alongside the task. This walkthrough shows how to define a concrete task, pause for compaction, recover the open requirements, and check the finished artifact against them.&lt;/p&gt;

&lt;p&gt;The example is a practice exercise, not a transcript of a measured experiment.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Install and activate
&lt;/h2&gt;

&lt;p&gt;Use a Codex surface that supports plugins and lifecycle Hooks. Follow the &lt;a href="https://github.com/GreenLv/codex-context-guard#install" rel="noopener noreferrer"&gt;current installation guide&lt;/a&gt; for the supported Python and Codex versions and the commands for your platform.&lt;/p&gt;

&lt;p&gt;Installation and Hook trust are separate steps. Start a fresh Codex task, open &lt;code&gt;/hooks&lt;/code&gt;, review and trust the plugin's Hook definitions, then start another fresh task in a disposable practice workspace. Existing tasks may retain the version they started with.&lt;/p&gt;

&lt;p&gt;In the Codex conversation, enter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$context-guard
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use &lt;code&gt;context-guard status&lt;/code&gt; to inspect the protected state. Enter these controls in the Codex conversation.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Give the task a concrete finish line
&lt;/h2&gt;

&lt;p&gt;Ask Codex to prepare a small design document using this synthetic brief:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;Create docs/design/checkout-v2.md for a practice checkout service.

Keep these decisions unchanged:

The API is POST /checkout.
The service validates the request before recording the order.
The rollout date is 2026-10-01.

Use these sections: Context, Decisions, Validation, Open Questions.
Do not add infrastructure commitments.
Give each recommendation a source link or a "to verify" label.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The file path makes the expected result concrete. The fixed decisions and section names give you things to compare with the final document. The source-link rule makes unsupported recommendations visible.&lt;/p&gt;

&lt;p&gt;Review the outline before proceeding. This pause is intentional: it leaves unfinished work available for the recovery exercise.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Compact, then inspect what survived
&lt;/h2&gt;

&lt;p&gt;At the pause, run &lt;code&gt;/compact&lt;/code&gt; in Codex. Once compaction finishes, enter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;context-guard status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Before continuing, restate the open requirements for
docs/design/checkout-v2.md, including the fixed decisions,
required sections, and evidence checks. Then write the file
and verify it against those requirements.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compare the recovered requirements with the original brief. Check the API, operation order, date, four sections, infrastructure restriction, and recommendation rule. A status count alone cannot establish that the right details survived.&lt;/p&gt;

&lt;p&gt;Context Guard's documented recovery behavior restores the open checklist after compaction or resume. Completed and historical work is tracked separately from the current work so earlier tasks do not automatically become new unfinished work.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Check the artifact and the evidence
&lt;/h2&gt;

&lt;p&gt;Have Codex read the finished file and report what it verified. For this example, the readback should establish that the named file exists, contains the four required sections, and preserves the API, operation order, and date. Review recommendations for a source link or the explicit uncertainty label, and inspect whether the draft introduces an infrastructure commitment.&lt;/p&gt;

&lt;p&gt;A successful formatting check only establishes formatting. It does not establish that the rollout date is correct or that a recommendation has support. Match each result to the requirement it actually checks, and review the cited sources yourself when their meaning matters.&lt;/p&gt;

&lt;p&gt;Context Guard uses successful tool evidence associated with the requested result when checking completion. Its deterministic checks have limits: it cannot establish that an arbitrary design is sound or that every source supports an interpretation. Unclear evidence should remain unresolved rather than become a claim of success.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Recognize the ending
&lt;/h2&gt;

&lt;p&gt;Normal successful paths are quiet. You do not need a special success receipt or private checkpoint command to finish an ordinary task.&lt;/p&gt;

&lt;p&gt;If Context Guard reports that the task is not yet safely complete, ask which requirement still lacks evidence. Use &lt;code&gt;context-guard diagnose&lt;/code&gt; for bounded diagnostic information, then address the missing check. A genuine pause for your input can end the turn while leaving the task unfinished.&lt;/p&gt;

&lt;p&gt;For your next task, choose one concrete artifact and write down its acceptance checks before work starts. After compaction, inspect the recovered requirements; before accepting completion, inspect the artifact and the evidence. Context Guard helps carry that workflow across a long conversation, while tests and human review remain essential.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://hol.org/registry/plugins/gerui-lv%2Fcontext-guard?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=blog_distribution&amp;amp;utm_content=context-guard-codex-compaction-evidence-workflow" rel="noopener noreferrer"&gt;Context Guard on HOL&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/GreenLv/codex-context-guard" rel="noopener noreferrer"&gt;Repository and current installation guide&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/GreenLv/codex-context-guard#try-it" rel="noopener noreferrer"&gt;Workflow documentation&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/GreenLv/codex-context-guard/releases/latest" rel="noopener noreferrer"&gt;Latest release&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>ScreenConnect client file runs hit CISA KEV</title>
      <dc:creator>Michael Kantor</dc:creator>
      <pubDate>Fri, 11 Sep 2026 20:41:48 +0000</pubDate>
      <link>https://dev.to/hol/screenconnect-client-file-runs-hit-cisa-kev-4dlc</link>
      <guid>https://dev.to/hol/screenconnect-client-file-runs-hit-cisa-kev-4dlc</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://hol.org/blog/cve-2026-84869-screenconnect-client-file-transfer-execution-kev" rel="noopener noreferrer"&gt;HOL&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CISA added CVE-2026-84869 to the Known Exploited Vulnerabilities catalog today (2026-09-11).&lt;/strong&gt; ConnectWise disclosed the bug on September 8 and shipped ScreenConnect 26.6.5 the same day. The failure is in the &lt;em&gt;client&lt;/em&gt;: during an active Support or Access session, file-transfer actions can land on the Host and run without the Host confirmation operators expect. That includes elevated execution paths. ScreenConnect servers are not in the blast radius.&lt;/p&gt;

&lt;p&gt;Cloud instances already run 26.6.5 on the server side. You still need to reinstall host clients and update access agents so the endpoints pick up the client fix. On-prem partners upgrade the server to 26.6.5 or later, then do the same client refresh. Federal KEV due date is 2026-09-14. Forensic triage is marked Yes.&lt;/p&gt;

&lt;h2&gt;
  
  
  What breaks
&lt;/h2&gt;

&lt;p&gt;ConnectWise rates CVE-2026-84869 Critical, CVSS 9.9 (&lt;code&gt;CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H&lt;/code&gt;). Weaknesses: missing authorization (CWE-862) and improper privilege management (CWE-269). Earlier ScreenConnect Client builds for Support and Access sessions processed file-transfer actions through an active remote session without proper authorization or Host confirmation. Under those conditions a Guest-side actor in the session can transfer a file to the Host and execute it, including elevated execution actions.&lt;/p&gt;

&lt;p&gt;Impacted product line: ScreenConnect versions prior to 26.6.5. Fixed line: ScreenConnect 26.6.5 and later. NVD published the record 2026-09-08.&lt;/p&gt;

&lt;p&gt;Priority on the ConnectWise bulletin is Priority 1 High: either being targeted or at higher risk of being targeted in the wild. Treat the client refresh as an emergency change, not a quiet backlog ticket.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who is not in scope
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;ScreenConnect servers&lt;/strong&gt; themselves. The advisory is explicit: servers are not impacted. This is a client/session handling bug, not a server RCE.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Idle boxes with no active remote session.&lt;/strong&gt; The condition rides an active Support or Access session. It is not "anyone on the internet can drop a binary with zero session."&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Cloud partners who already reinstalled host clients and access agents after the 26.6.5 cloud push.&lt;/strong&gt; The server is already remediated in cloud; remaining risk is stale clients.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;On-prem installs that cannot reach 26.6.5 yet because they are below 25.4.&lt;/strong&gt; ConnectWise requires 25.4 or later before the 26.6.5 upgrade path. Those partners still need a plan (upgrade train, license eligibility, or TransferFiles mitigation below), but the 26.6.5 installer is not the first click.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  One operator check
&lt;/h2&gt;

&lt;p&gt;On the ScreenConnect instance, open &lt;strong&gt;Administration → Overview&lt;/strong&gt; and read the current version. Anything prior to &lt;code&gt;26.6.5&lt;/code&gt; is still on the vulnerable train for on-prem. Cloud partners should see &lt;code&gt;26.6.5&lt;/code&gt; on Overview already; then verify host clients and access agents were actually reinstalled or updated after that push, not just that the server badge moved.&lt;/p&gt;

&lt;p&gt;While you wait for a maintenance window, cut the immediate path: &lt;strong&gt;Administration → Security → Roles&lt;/strong&gt;, edit each role, and deselect &lt;code&gt;TransferFiles&lt;/code&gt; on every session group that has it. Save. Repeat for each role. ConnectWise calls this temporary mitigation, not a substitute for 26.6.5.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to fix
&lt;/h2&gt;

&lt;p&gt;Upgrade ScreenConnect to &lt;code&gt;26.6.5&lt;/code&gt; or later, then refresh every host client and access agent.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Cloud:&lt;/strong&gt; server side is already updated. Reinstall host clients and update access agents per ConnectWise docs so endpoints leave the vulnerable client build.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;On-prem:&lt;/strong&gt; download 26.6.5 from the ScreenConnect download page (valid on-prem license required). Confirm &lt;strong&gt;Latest Eligible Version&lt;/strong&gt; on Administration → Overview before you install. If the license is out of maintenance, renew or upgrade the license first. Automate-integrated on-prem installs pull 26.6.5 through Automate Product Updates when Automate Assurance is active.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;After the server bump:&lt;/strong&gt; reinstall host clients and update access agents the same way cloud partners must. Patching the server alone does not retire every stale client.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Interim:&lt;/strong&gt; strip &lt;code&gt;TransferFiles&lt;/code&gt; from roles as above until 26.6.5 is live everywhere that matters.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ConnectWise also tells partners to review users with ScreenConnect access after the patch: remove unused accounts, re-check role grants, and treat unexpected session or transfer history as investigation material. That matches CISA's forensic-triage flag on this KEV entry.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this is not
&lt;/h2&gt;

&lt;p&gt;This is not an unauthenticated internet worm that pops ScreenConnect servers with no session. It is a client-side authorization failure during an already-active remote session: file transfer and execution without the Host confirmation operators rely on. Do not skip the client refresh because "cloud already says 26.6.5."&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://www.connectwise.com/company/trust/security-bulletins/2026-09-08-screenconnect-bulletin" rel="noopener noreferrer"&gt;ConnectWise Security Bulletin - ScreenConnect (2026-09-08)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/ConnectWise-Advisories/Disclosures/tree/main/CVE-2026-84869" rel="noopener noreferrer"&gt;ConnectWise Advisories disclosure for CVE-2026-84869&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.cisa.gov/known-exploited-vulnerabilities-catalog?field_cve=CVE-2026-84869" rel="noopener noreferrer"&gt;CISA Known Exploited Vulnerabilities entry&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://nvd.nist.gov/vuln/detail/CVE-2026-84869" rel="noopener noreferrer"&gt;NVD - CVE-2026-84869&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://hol.org/guard/security/cves/CVE-2026-84869?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=blog_distribution&amp;amp;utm_content=cve-2026-84869-screenconnect-client-file-transfer-execution-kev" rel="noopener noreferrer"&gt;HOL Guard evidence pack&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cve</category>
      <category>screenconnect</category>
      <category>connectwise</category>
      <category>kev</category>
    </item>
    <item>
      <title>Self-managed GitLab: unauth commits API file read hits CISA KEV</title>
      <dc:creator>Michael Kantor</dc:creator>
      <pubDate>Fri, 11 Sep 2026 20:17:34 +0000</pubDate>
      <link>https://dev.to/hol/self-managed-gitlab-unauth-commits-api-file-read-hits-cisa-kev-22di</link>
      <guid>https://dev.to/hol/self-managed-gitlab-unauth-commits-api-file-read-hits-cisa-kev-22di</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://hol.org/blog/cve-2026-85706-gitlab-commits-api-path-traversal-kev" rel="noopener noreferrer"&gt;HOL&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CISA added CVE-2026-85706 to the Known Exploited Vulnerabilities catalog today (2026-09-11).&lt;/strong&gt; GitLab shipped the Critical Patch Release that closes it on September 10: 19.1.8 / 19.2.6 / 19.3.2. The bug is an unauthenticated path traversal in the repository commits API. Anyone who can reach a vulnerable self-managed instance can read arbitrary files off the GitLab server. That means repo secrets, SSH keys, &lt;code&gt;.env&lt;/code&gt; files, and whatever else sits on disk under the GitLab service account.&lt;/p&gt;

&lt;p&gt;GitLab.com is already patched. Dedicated customers have nothing to do. Self-managed operators on 18.7 through unpatched 19.3.x need to upgrade now. Federal agencies on KEV have a due date of 2026-09-14 and forensic triage is marked Yes.&lt;/p&gt;

&lt;h2&gt;
  
  
  What breaks
&lt;/h2&gt;

&lt;p&gt;GitLab rates CVE-2026-85706 Critical, CVSS 10.0 (&lt;code&gt;CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N&lt;/code&gt;). Improper path confinement plus missing auth enforcement on the repository commits API let an unauthenticated caller pull files from the server. Impacted: GitLab CE/EE all versions from 18.7 before 19.1.8, 19.2 before 19.2.6, and 19.3 before 19.3.2. Reporter: s3ntago via HackerOne. CWE-35.&lt;/p&gt;

&lt;p&gt;The same Critical Patch Release also closes two EE-only siblings you should treat as part of the same upgrade, not separate tickets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;CVE-2026-87719&lt;/strong&gt; Critical CVSS 9.9. Insecure deserialization in the GraphQL subscription serializer. An authenticated user with Duo Chat access can obtain Advanced Search instance configs and credentials via a crafted subscription argument. EE only, from 18.3 before the same fixed trains.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;CVE-2026-88765&lt;/strong&gt; High CVSS 8.5. Buffer overflow in a Unicode conversion wrapper used by Advanced Search indexing. An authenticated user can reach RCE by importing a crafted project export. EE only, from 12.3 before the same fixed trains. Attack complexity is High.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lead with 85706. It needs no login, hits CE and EE, and is on KEV. The other two ride along when you upgrade.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who is not in scope
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;GitLab.com&lt;/strong&gt; already runs the patched build. No action.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;GitLab Dedicated&lt;/strong&gt; customers: vendor says no action required.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Versions before 18.7&lt;/strong&gt; for CVE-2026-85706. The commits-API path traversal range starts at 18.7.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;CVE-2026-87719 and CVE-2026-88765&lt;/strong&gt; are Enterprise Edition only. CE instances are out of scope for those two. Both also need authentication (Duo Chat for 87719; project-import / Advanced Search path for 88765).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Operator check
&lt;/h2&gt;

&lt;p&gt;Confirm your version before you declare yourself clear:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Omnibus / package&lt;/span&gt;
dpkg &lt;span class="nt"&gt;-l&lt;/span&gt; gitlab-ce gitlab-ee 2&amp;gt;/dev/null | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s1"&gt;'gitlab-(ce|ee)'&lt;/span&gt;
&lt;span class="c"&gt;# or&lt;/span&gt;
rpm &lt;span class="nt"&gt;-q&lt;/span&gt; gitlab-ce gitlab-ee 2&amp;gt;/dev/null

From the Rails console / rake helper
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the Admin UI: &lt;strong&gt;Admin Area → Overview → Dashboard&lt;/strong&gt; shows the running version. You need &lt;code&gt;≥ 19.1.8&lt;/code&gt; on the 19.1 train, &lt;code&gt;≥ 19.2.6&lt;/code&gt; on 19.2, or &lt;code&gt;≥ 19.3.2&lt;/code&gt; on 19.3. Anything 18.7.x through unpatched 19.3.1 is still in the 85706 window.&lt;/p&gt;

&lt;p&gt;If the instance is internet-facing and unpatched, treat file-read of secrets on the GitLab host as a realistic outcome and rotate credentials that lived under that service account after you upgrade.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to fix
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Debian/Ubuntu Omnibus CE example (match your edition + train)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;gitlab-ce&lt;span class="o"&gt;=&lt;/span&gt;19.3.2-&lt;span class="k"&gt;*&lt;/span&gt;
&lt;span class="c"&gt;# or 19.2.6-* / 19.1.8-* on older supported trains&lt;/span&gt;

RHEL/CentOS Omnibus
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Follow GitLab's Update docs for your install type (Omnibus, Helm, source). This patch includes database migrations. Single-node installs will take downtime while migrations finish. Multi-node can use zero-downtime procedures. 19.3.2 also ships post-deploy migrations you can run after the upgrade.&lt;/p&gt;

&lt;p&gt;GitLab Runner updates are separate; bump the application first for these CVEs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this is not
&lt;/h2&gt;

&lt;p&gt;CVE-2026-85706 is arbitrary &lt;strong&gt;file read&lt;/strong&gt;, not remote code execution by itself. It is not a worm. SaaS / GitLab.com is already fixed. The blast radius that matters is self-managed, internet-facing instances on 18.7 through unpatched 19.3.x. The EE siblings (87719 / 88765) need auth and product features (Duo Chat / Advanced Search import) that not every install enables.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://docs.gitlab.com/releases/patches/patch-release-gitlab-19-3-2-released/" rel="noopener noreferrer"&gt;GitLab Critical Patch Release: 19.3.2, 19.2.6, 19.1.8&lt;/a&gt; (2026-09-10)&lt;/li&gt;
&lt;li&gt;  CISA KEV: CVE-2026-85706, dateAdded 2026-09-11, dueDate 2026-09-14, forensicTriage Yes&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cve</category>
      <category>gitlab</category>
      <category>pathtraversal</category>
      <category>kev</category>
    </item>
    <item>
      <title>Your agent tried to ship your AWS keys</title>
      <dc:creator>Michael Kantor</dc:creator>
      <pubDate>Fri, 11 Sep 2026 19:38:41 +0000</pubDate>
      <link>https://dev.to/hol/your-agent-tried-to-ship-your-aws-keys-3ajb</link>
      <guid>https://dev.to/hol/your-agent-tried-to-ship-your-aws-keys-3ajb</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://hol.org/blog/guard-protects-credential-exfil-curl" rel="noopener noreferrer"&gt;HOL&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You left &lt;a href="https://hol.org/guard/ai-coding-agents?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=blog_distribution&amp;amp;utm_content=guard-protects-credential-exfil-curl" rel="noopener noreferrer"&gt;Claude Code&lt;/a&gt; running. Mid-session it tried to send your AWS keys to a website you never opened. Whoever gets those keys can spin up servers on your bill. That is the laptop you code on.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hol.org/guard/features?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=blog_distribution&amp;amp;utm_content=guard-protects-credential-exfil-curl" rel="noopener noreferrer"&gt;HOL Guard&lt;/a&gt; caught the send and froze it before it left the machine. Two buttons on screen: &lt;strong&gt;Allow just this once&lt;/strong&gt;, or &lt;strong&gt;Keep blocked&lt;/strong&gt;. Do not tap Allow and the keys stay on the laptop. The assistant does not click for you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbsb9ghm7sd6vt9xpvu6g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbsb9ghm7sd6vt9xpvu6g.png" alt="HOL Guard Inbox review: PAUSED ACTION Needs review, Allow just this once and Keep blocked"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Local Inbox review for a paused Claude Code command. Queue shows the curl; the card is PAUSED ACTION / Needs review with Allow just this once and Keep blocked.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4002rzlua9jtdk8stwox.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4002rzlua9jtdk8stwox.png" alt="Close-up of Allow just this once (green) and Keep blocked buttons on HOL Guard review card"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Button labels on the live review card: Allow just this once, Keep blocked. Scope defaults to a one-time allow for this exact action.&lt;/p&gt;

&lt;p&gt;Keep blocked leaves the action stopped. The receipt stays on your machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Guard is watching for
&lt;/h2&gt;

&lt;p&gt;This shape maps to the built-in &lt;a href="https://hol.org/guard/extensions/command.data-protection?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=blog_distribution&amp;amp;utm_content=guard-protects-credential-exfil-curl" rel="noopener noreferrer"&gt;Command data protection&lt;/a&gt; Extension (&lt;code&gt;command.data-protection&lt;/code&gt;, v1.0.0). Catalog default for both operations is review:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Credential data transfer&lt;/strong&gt; (&lt;code&gt;command.data-protection.permission.credential-exfiltration&lt;/code&gt;). Curl that posts a cloud credentials file off the machine.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Local file upload&lt;/strong&gt; (&lt;code&gt;command.data-protection.permission.file-upload&lt;/code&gt;). Curl that uploads a local report PDF.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Exact credential-file curl strings live on that directory page. This post uses a &lt;code&gt;/tmp&lt;/code&gt; dummy for the live demo so the write path stays clear of filters that trip on home credential paths.&lt;/p&gt;

&lt;p&gt;A workspace can tighten to block or loosen the floor unless a managed-restrictive Control Set pins the Extension. Catalog default is not your fleet policy.&lt;/p&gt;

&lt;p&gt;Live proof used a dummy under &lt;code&gt;/tmp&lt;/code&gt;. &lt;code&gt;hol-guard command test&lt;/code&gt; on that line returned REVIEW under &lt;code&gt;command.data-protection.file-upload&lt;/code&gt;, with risks &lt;code&gt;credential_exfiltration&lt;/code&gt; and &lt;code&gt;network_egress&lt;/code&gt;. The same shape under a PreToolUse hook landed in Inbox as Needs review.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F48mko1ddayg9dz4a2p9x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F48mko1ddayg9dz4a2p9x.png" alt="HOL Guard Settings Protection: Protected, Extra careful, Watch"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Settings → Protection: Protected (default), Extra careful, Watch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fufo2r125is0fr68uqz9m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fufo2r125is0fr68uqz9m.png" alt="HOL Guard Extensions modules list in the local dashboard"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Extensions / Modules in the local dashboard. &lt;code&gt;command.data-protection&lt;/code&gt; ships built-in.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the pause shows up
&lt;/h2&gt;

&lt;p&gt;Guard Core owns policy, approvals, receipts, the daemon, and the local dashboard. Guard Desktop is the optional tray UI. Closing the tray does not turn enforcement off. Install from &lt;a href="https://hol.org/guard/install?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=blog_distribution&amp;amp;utm_content=guard-protects-credential-exfil-curl" rel="noopener noreferrer"&gt;hol.org/guard/install&lt;/a&gt; if you want the tray; local by default, Cloud sync optional.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftwj4ss0t3e3dtrth9sfk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftwj4ss0t3e3dtrth9sfk.png" alt="HOL Guard Desktop install page with download for Linux, Apple silicon, and Windows"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Install Guard Desktop from hol.org/guard/install when you want the tray UI.&lt;/p&gt;

&lt;p&gt;Agent tool use hits a PreToolUse hook; Guard parses the line once; Inbox offers Allow just this once or Keep blocked. Protect / Extensions sets posture: Protected (default), Extra careful, or Watch. Watch records without stopping. Approvals also work from &lt;code&gt;hol-guard approvals&lt;/code&gt; in a terminal you control.&lt;/p&gt;

&lt;h2&gt;
  
  
  Out of scope
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;command.data-protection&lt;/code&gt; does not cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Reading a secret file locally with &lt;code&gt;cat&lt;/code&gt; or an editor. Mapped ops are send and upload.&lt;/li&gt;
&lt;li&gt;  Browser MCP tools posting a form.&lt;/li&gt;
&lt;li&gt;  Package installs (&lt;code&gt;npx&lt;/code&gt;, &lt;code&gt;pip&lt;/code&gt;): Package Firewall Extensions.&lt;/li&gt;
&lt;li&gt;  Decode-and-execute shell chains: &lt;code&gt;command.encoded-execution&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  An agent calling &lt;code&gt;hol-guard approvals approve&lt;/code&gt; on itself: &lt;code&gt;command.guard-self-protection&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  One check that does not run curl
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;command test&lt;/code&gt; and &lt;code&gt;command explain&lt;/code&gt; do not execute the command, create an approval, or write a receipt.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hol-guard command test '&amp;lt;WAF-safe dummy: curl posts /tmp/demo-cloud-keys to example.com&amp;gt;'
hol-guard command explain '&amp;lt;catalog file-upload example from directory page&amp;gt;'
hol-guard command controls show command.data-protection
hol-guard command extensions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rehearse with a &lt;code&gt;/tmp&lt;/code&gt; dummy path (not a home credentials path). The live proof shape returned REVIEW under &lt;code&gt;command.data-protection.file-upload&lt;/code&gt;. Copy catalog examples from the directory page for the literal credential-file strings. After an upgrade, run the test before you trust muscle memory. If test says unrecognized, confirm the Extension is current and posture is not Watch.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this does not claim
&lt;/h2&gt;

&lt;p&gt;This is a pause on two send and upload shapes Guard already intercepts. It will not stop every outbound curl. Reading a secret file in an editor is not this Extension.&lt;/p&gt;

&lt;p&gt;Change the permission in Protect / Extensions or via CLI. For a team floor local auto-approve settings cannot weaken, use a managed-restrictive Control Set on this Extension's permission IDs.&lt;/p&gt;

&lt;p&gt;If you meant the upload, choose Allow just this once with your eyes on the URL. If you did not, Keep blocked and find which prompt or MCP tool suggested the curl. Receipt stays local. Cloud sync is optional and does not carry the raw command.&lt;/p&gt;

&lt;p&gt;Background: &lt;a href="https://hol.org/blog/hol-guard-3-0-extension-first-managed-controls?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=blog_distribution&amp;amp;utm_content=guard-protects-credential-exfil-curl" rel="noopener noreferrer"&gt;HOL Guard 3.0&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>holguard</category>
      <category>guardextensions</category>
      <category>credentialexfiltration</category>
      <category>agentsecurity</category>
    </item>
    <item>
      <title>Artifactory anonymous token chain hits CISA KEV</title>
      <dc:creator>Michael Kantor</dc:creator>
      <pubDate>Fri, 11 Sep 2026 19:26:25 +0000</pubDate>
      <link>https://dev.to/hol/artifactory-anonymous-token-chain-hits-cisa-kev-23mn</link>
      <guid>https://dev.to/hol/artifactory-anonymous-token-chain-hits-cisa-kev-23mn</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://hol.org/blog/cve-2026-42018-artifactory-anonymous-token-kev-chain" rel="noopener noreferrer"&gt;HOL&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CISA put CVE-2026-42018 and CVE-2026-42016 on the Known Exploited Vulnerabilities catalog today (2026-09-11).&lt;/strong&gt; Wiz Research already documented in-the-wild chaining of those two bugs on self-hosted JFrog Artifactory: an unauthenticated call mints an internal anonymous JWT, then that low-privilege token is exchanged for admin scope. Operators who only chased CVE-2026-82329 (the join-key path we covered on 28 Aug) can still be open on this older pair.&lt;/p&gt;

&lt;p&gt;Upgrade self-hosted Artifactory to a build that clears both CVEs on your train. Prefer the later trains JFrog listed for the Critical sibling as well: &lt;code&gt;7.111.21&lt;/code&gt;, &lt;code&gt;7.117.28&lt;/code&gt;, &lt;code&gt;7.125.20&lt;/code&gt;, &lt;code&gt;7.133.29&lt;/code&gt;, &lt;code&gt;7.146.38&lt;/code&gt;, or &lt;code&gt;7.161.20&lt;/code&gt;. Then hunt logs for the chain below.&lt;/p&gt;

&lt;h2&gt;
  
  
  What breaks
&lt;/h2&gt;

&lt;p&gt;JFrog rates CVE-2026-42018 High (CWE-287). Published 12 Aug 2026. Artifactory can return an internal anonymous-user token to an unauthenticated caller even when anonymous access is disabled. Fixed builds on the advisory: &lt;code&gt;7.111.20&lt;/code&gt;, &lt;code&gt;7.117.27&lt;/code&gt;, &lt;code&gt;7.125.19&lt;/code&gt;, &lt;code&gt;7.133.28&lt;/code&gt;, &lt;code&gt;7.146.8&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;JFrog rates CVE-2026-42016 High (CWE-863). Published 27 Jul 2026. Token validation checks signature and issuer but not intended scope, so a low-privilege token can be escalated. The advisory lists a single fixed floor: &lt;code&gt;7.133.11&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Neither bug alone is full admin. Together they are. Wiz's observed sequence (Aug 15 through Sep 8, 2026):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;code&gt;POST /access/api/v1/aws/token/&lt;/code&gt; with a trailing slash returns HTTP 200 and a JWT for the internal anonymous user (CVE-2026-42018).&lt;/li&gt;
&lt;li&gt; &lt;code&gt;POST /access/api/v1/tokens&lt;/code&gt; exchanges that JWT for an admin-scoped token while the username stays anonymous (CVE-2026-42016).&lt;/li&gt;
&lt;li&gt; Actors then create persistent admins via &lt;code&gt;PUT /api/security/users/...&lt;/code&gt; or &lt;code&gt;/access/api/ui/users/...&lt;/code&gt;, install malicious Groovy plugins, run &lt;code&gt;/api/plugins/execute/...&lt;/code&gt;, and in several cases drop a Rust C2 binary under &lt;code&gt;/dev/shm&lt;/code&gt;, &lt;code&gt;/tmp&lt;/code&gt;, or &lt;code&gt;/var/tmp&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Wiz notes a useful probe signature for 42018: the same client gets 401 on the bare path, then 200 on a trailing-slash or path variant, inside a short window. Later requests often show actor &lt;code&gt;token:anonymous&lt;/code&gt; doing admin work. That is not normal operator traffic.&lt;/p&gt;

&lt;p&gt;Exposure when those CVEs first published was not a niche corner case. Wiz measured about two-thirds of organizations with Artifactory still holding at least one vulnerable instance at disclosure, with slow patch velocity on the High pair versus the Critical 82329.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who is not in scope
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  JFrog Cloud. Both advisories say affected Cloud environments were already fortified.&lt;/li&gt;
&lt;li&gt;  Self-hosted nodes already on fixed builds for &lt;em&gt;both&lt;/em&gt; CVEs on your train. Clearing only 42016 or only 42018 breaks the published chain; clearing neither leaves it open.&lt;/li&gt;
&lt;li&gt;  The CVE-2026-82329 join-key path (&lt;code&gt;POST /access/api/v1/registry/join&lt;/code&gt;). That is a different unauth-admin bug with its own ranges and KEV add on 2026-09-02. Patching 82329 does not automatically mean you cleared 42018/42016.&lt;/li&gt;
&lt;li&gt;  Branches where JFrog's 42016 advisory does not claim impact. JFrog only listed "&amp;lt; 7.133.11" for 42016. Do not invent that 7.146/7.161 are vulnerable to 42016, and do not invent that they are immune to 42018 without checking the 42018 table.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to check
&lt;/h2&gt;

&lt;p&gt;Confirm product version (not a single microservice build):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jf rt curl /api/system/version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compare &lt;code&gt;version&lt;/code&gt; to the fixed floors above. If you are still below &lt;code&gt;7.146.8&lt;/code&gt; on the 7.146 train, or below &lt;code&gt;7.133.28&lt;/code&gt; / &lt;code&gt;7.133.11&lt;/code&gt; on 7.133, treat the chain as open until proven otherwise.&lt;/p&gt;

&lt;p&gt;Then search Access / reverse-proxy logs for the Wiz sequence: unauthenticated &lt;code&gt;POST /access/api/v1/aws/token/&lt;/code&gt; (trailing slash) returning 200, followed quickly by &lt;code&gt;POST /access/api/v1/tokens&lt;/code&gt;, then admin user creates. Flag accounts matching patterns Wiz reported (&lt;code&gt;Nxploited_*&lt;/code&gt;, &lt;code&gt;labadmin_*&lt;/code&gt;, &lt;code&gt;svc_*&lt;/code&gt;, &lt;code&gt;jfrog-distribution&lt;/code&gt;, &lt;code&gt;repo-service&lt;/code&gt;, &lt;code&gt;0xTerror&lt;/code&gt;, and similar). Pull join keys and token inventories if those endpoints were hit.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to fix
&lt;/h2&gt;

&lt;p&gt;Upgrade self-hosted Artifactory on your current train to builds that include the 42018 and 42016 fixes. Practical target set that also clears the Critical sibling many fleets still chase:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;7.161.x&lt;/code&gt; → &lt;code&gt;7.161.20&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;7.146.x&lt;/code&gt; → &lt;code&gt;7.146.38&lt;/code&gt; (42018 floor on this train was &lt;code&gt;7.146.8&lt;/code&gt;; take the later Critical build)&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;7.133.x&lt;/code&gt; → &lt;code&gt;7.133.29&lt;/code&gt; (must be at least &lt;code&gt;7.133.28&lt;/code&gt; for 42018 and &lt;code&gt;7.133.11&lt;/code&gt; for 42016)&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;7.125.x&lt;/code&gt; → &lt;code&gt;7.125.20&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;7.117.x&lt;/code&gt; → &lt;code&gt;7.117.28&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;7.111.x&lt;/code&gt; → &lt;code&gt;7.111.21&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CISA KEV dateAdded for both CVEs is 2026-09-11 (catalogVersion 2026.09.11). dueDate is 2026-09-25. Follow BOD 26-04 and the forensic triage requirements linked from the KEV notes. After upgrade, re-run the version API and require an exact match on a patched string. Restrict the Access API from the public internet while you patch.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this is not
&lt;/h2&gt;

&lt;p&gt;This is not a JFrog Cloud emergency. It is not remote code execution by itself. Admin on Artifactory is the vendor impact; shells and Rust backdoors showed up after actors abused plugins and write paths. It is not CVE-2026-82329 (different endpoint, Critical, KEV 2026-09-02). It is not "anonymous access was left on." Wiz and JFrog both describe token minting while anonymous access is disabled.&lt;/p&gt;

&lt;p&gt;This article is the operator write-up for the KEV / in-the-wild chain. The HOL Guard evidence pages remain the source records for &lt;a href="https://hol.org/guard/security/cves/CVE-2026-42018?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=blog_distribution&amp;amp;utm_content=cve-2026-42018-artifactory-anonymous-token-kev-chain" rel="noopener noreferrer"&gt;CVE-2026-42018&lt;/a&gt; and &lt;a href="https://hol.org/guard/security/cves/CVE-2026-42016?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=blog_distribution&amp;amp;utm_content=cve-2026-42018-artifactory-anonymous-token-kev-chain" rel="noopener noreferrer"&gt;CVE-2026-42016&lt;/a&gt;. Our earlier operator post on the Critical sibling is &lt;a href="https://hol.org/blog/cve-2026-82329-jfrog-artifactory-unauth-admin-default?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=blog_distribution&amp;amp;utm_content=cve-2026-42018-artifactory-anonymous-token-kev-chain" rel="noopener noreferrer"&gt;CVE-2026-82329&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://docs.jfrog.com/releases/docs/jfrog-security-advisories" rel="noopener noreferrer"&gt;JFrog Security Advisories (CVE-2026-42018, CVE-2026-42016)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.wiz.io/blog/artifactory-under-attack-in-the-wild-exploitation-of-cve-2026-42016-cve-2026-4201" rel="noopener noreferrer"&gt;Wiz: Artifactory under attack (in-the-wild chain)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.cisa.gov/known-exploited-vulnerabilities-catalog" rel="noopener noreferrer"&gt;CISA KEV catalog (added 2026-09-11)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://hol.org/blog/cve-2026-82329-jfrog-artifactory-unauth-admin-default?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=blog_distribution&amp;amp;utm_content=cve-2026-42018-artifactory-anonymous-token-kev-chain" rel="noopener noreferrer"&gt;HOL: CVE-2026-82329 Artifactory unauth admin&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://hol.org/guard/security/cves/CVE-2026-42018?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=blog_distribution&amp;amp;utm_content=cve-2026-42018-artifactory-anonymous-token-kev-chain" rel="noopener noreferrer"&gt;HOL Guard CVE-2026-42018&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://hol.org/guard/security/cves/CVE-2026-42016?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=blog_distribution&amp;amp;utm_content=cve-2026-42018-artifactory-anonymous-token-kev-chain" rel="noopener noreferrer"&gt;HOL Guard CVE-2026-42016&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cve</category>
      <category>jfrog</category>
      <category>artifactory</category>
      <category>kev</category>
    </item>
    <item>
      <title>CVE-2026-71416: Headroom WebSocket proxy spends your OpenAI key for any reachable browser</title>
      <dc:creator>Michael Kantor</dc:creator>
      <pubDate>Fri, 11 Sep 2026 14:26:23 +0000</pubDate>
      <link>https://dev.to/hol/cve-2026-71416-headroom-websocket-proxy-spends-your-openai-key-for-any-reachable-browser-35a</link>
      <guid>https://dev.to/hol/cve-2026-71416-headroom-websocket-proxy-spends-your-openai-key-for-any-reachable-browser-35a</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://hol.org/blog/cve-2026-71416-headroom-websocket-origin-cswsh-openai-key" rel="noopener noreferrer"&gt;HOL&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If a browser on your network can open &lt;code&gt;ws://your-host:8787/v1/responses&lt;/code&gt;, it can ride Headroom's stored OpenAI key.&lt;/strong&gt; Before &lt;code&gt;headroom-ai&lt;/code&gt; 0.35.0, the Responses WebSocket handler accepted the upgrade without checking &lt;code&gt;Origin&lt;/code&gt;, then injected &lt;code&gt;Authorization: Bearer $OPENAI_API_KEY&lt;/code&gt; when the client sent none. A malicious page (or headless browser) that can reach that listener spends your quota, drives arbitrary prompts and tools, and can reach RCE if the upstream session exposes a shell tool. CVE-2026-71416 is the Sept 11 ID for a fix that already shipped in 0.35.0 on Aug 13.&lt;/p&gt;

&lt;p&gt;Upgrade to &lt;code&gt;headroom-ai&amp;gt;=0.35.0&lt;/code&gt; (current line is 0.37.0). If you must stay on an older build, do not bind the proxy where browsers can reach it, and do not keep &lt;code&gt;OPENAI_API_KEY&lt;/code&gt; in the proxy process environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  What breaks
&lt;/h2&gt;

&lt;p&gt;GitHub advisory &lt;a href="https://github.com/headroomlabs-ai/headroom/security/advisories/GHSA-h46j-26q3-rggf" rel="noopener noreferrer"&gt;GHSA-h46j-26q3-rggf&lt;/a&gt; / CVE-2026-71416 rates this High (CVSS 8.8, AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H). User interaction is required in the CVSS sense (a browser must run the malicious WebSocket client), but no Headroom login is required once the page can reach the proxy. The GHSA PoC targets &lt;code&gt;ws://&amp;lt;host&amp;gt;:8787/v1/responses&lt;/code&gt; with a &lt;code&gt;response.create&lt;/code&gt; payload, including a local shell tool.&lt;/p&gt;

&lt;p&gt;The advisory explains the missing check and the env-var auth fallback. The Aug 13 0.35.0 patch does three things the GHSA does not spell out. It rejects disallowed origins with WebSocket close code &lt;code&gt;1008&lt;/code&gt; and reason &lt;code&gt;origin not allowed&lt;/code&gt;, logging &lt;code&gt;event=websocket_origin_not_allowed&lt;/code&gt;. Native clients that omit &lt;code&gt;Origin&lt;/code&gt; still pass. When &lt;code&gt;Origin&lt;/code&gt; is present and you have not configured an allowlist, only loopback origins are accepted. Operators set the allowlist with &lt;code&gt;HEADROOM_WS_ORIGINS&lt;/code&gt; (comma-separated); if that is empty, Headroom also reads &lt;code&gt;HEADROOM_CORS_ORIGINS&lt;/code&gt;. A literal &lt;code&gt;*&lt;/code&gt; in the list re-opens every origin.&lt;/p&gt;

&lt;p&gt;PyPI package name is &lt;code&gt;headroom-ai&lt;/code&gt; (not the unrelated &lt;code&gt;headroom&lt;/code&gt; package). GitHub shows about 71k stars; PyPI recent downloads for &lt;code&gt;headroom-ai&lt;/code&gt; are on the order of hundreds of thousands per month. Affected: &lt;code&gt;headroom-ai &amp;lt; 0.35.0&lt;/code&gt; (GHSA marks the vulnerable train from 0.23.0). Fixed: &lt;code&gt;0.35.0&lt;/code&gt; and later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who is not in scope
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  Installs already on &lt;code&gt;headroom-ai&amp;gt;=0.35.0&lt;/code&gt; (0.35.0 hit PyPI 2026-08-13; 0.37.0 is current).&lt;/li&gt;
&lt;li&gt;  Library-only or MCP-only usage that never runs the local OpenAI Responses WebSocket proxy on &lt;code&gt;/v1/responses&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Proxies that never store &lt;code&gt;OPENAI_API_KEY&lt;/code&gt; in the process environment and require the client to send its own &lt;code&gt;Authorization&lt;/code&gt; header (the GHSA exploit path relies on the env-var injection).&lt;/li&gt;
&lt;li&gt;  Listeners that browsers cannot reach (true localhost-only bind with no malicious local content, or network policy that blocks the WS port).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to check
&lt;/h2&gt;

&lt;p&gt;From the environment that runs the proxy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;pip show headroom-ai
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Any printed version below &lt;code&gt;0.35.0&lt;/code&gt; is vulnerable. Also confirm whether the proxy process exports &lt;code&gt;OPENAI_API_KEY&lt;/code&gt; and whether anything listens on port &lt;code&gt;8787&lt;/code&gt; (or your configured proxy port) beyond loopback. After upgrade, if browsers on other origins must use the WS endpoint, set an explicit allowlist rather than relying on the loopback default:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;HEADROOM_WS_ORIGINS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://app.example.com,http://127.0.0.1:3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to fix
&lt;/h2&gt;

&lt;p&gt;Upgrade headroom-ai to the patched release or newer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;pip install 'headroom-ai&amp;gt;&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0.35.0&lt;span class="s1"&gt;'
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart the proxy. Prefer not to put long-lived provider keys in the proxy environment if clients can supply their own auth. Do not set &lt;code&gt;HEADROOM_WS_ORIGINS=*&lt;/code&gt; unless you fully trust every browser that can reach the listener.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this is not
&lt;/h2&gt;

&lt;p&gt;This is not a bug in OpenAI, and it is not unauthenticated RCE inside the Headroom process itself. Damage is CSWSH against the proxy: a reachable WebSocket plus a stored provider key. RCE appears only when the proxied session can invoke dangerous tools (for example a local shell tool). CVE assignment landed about a month after 0.35.0 shipped; the upgrade urgency is for fleets still below that floor.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://github.com/headroomlabs-ai/headroom/security/advisories/GHSA-h46j-26q3-rggf" rel="noopener noreferrer"&gt;GHSA-h46j-26q3-rggf&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.cve.org/CVERecord?id=CVE-2026-71416" rel="noopener noreferrer"&gt;CVE-2026-71416&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/headroomlabs-ai/headroom/commit/c632023cc1ec61d15f8f8e86efe3b54d51604a64" rel="noopener noreferrer"&gt;Origin validation patch (close 1008 / HEADROOM_WS_ORIGINS)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/headroomlabs-ai/headroom/releases/tag/v0.35.0" rel="noopener noreferrer"&gt;headroom-ai 0.35.0 release&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://hol.org/guard/security/cves/CVE-2026-71416-headroom-vulnerable-to-cross-site-websocket?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=blog_distribution&amp;amp;utm_content=cve-2026-71416-headroom-websocket-origin-cswsh-openai-key" rel="noopener noreferrer"&gt;HOL Guard evidence pack for CVE-2026-71416&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cve</category>
      <category>headroom</category>
      <category>headroomai</category>
      <category>websocket</category>
    </item>
    <item>
      <title>CVE-2026-87776: Express compression leaks native memory until the process dies</title>
      <dc:creator>Michael Kantor</dc:creator>
      <pubDate>Fri, 11 Sep 2026 13:23:06 +0000</pubDate>
      <link>https://dev.to/hol/cve-2026-87776-express-compression-leaks-native-memory-until-the-process-dies-ajo</link>
      <guid>https://dev.to/hol/cve-2026-87776-express-compression-leaks-native-memory-until-the-process-dies-ajo</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://hol.org/blog/cve-2026-87776-express-compression-zlib-abort-memory-dos" rel="noopener noreferrer"&gt;HOL&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hang up while gzip is still streaming and the Node process keeps the zlib memory forever.&lt;/strong&gt; The Express &lt;code&gt;compression&lt;/code&gt; middleware (&lt;code&gt;&amp;lt; 1.8.2&lt;/code&gt;) only tears down its compression stream from inside its own &lt;code&gt;res.end()&lt;/code&gt; wrapper. When a client aborts mid-response, that wrapper never runs, so each aborted compressed reply leaves a live native zlib handle pinned. Repeat it and RSS climbs until the process is OOM-killed. The bug is unauthenticated and needs no app bug beyond shipping compression.&lt;/p&gt;

&lt;p&gt;Upgrade to &lt;code&gt;compression@1.8.2&lt;/code&gt;. There is no application-level workaround in the advisory.&lt;/p&gt;

&lt;h2&gt;
  
  
  What breaks
&lt;/h2&gt;

&lt;p&gt;GitHub advisory &lt;a href="https://github.com/expressjs/compression/security/advisories/GHSA-vc2v-76pw-4v95" rel="noopener noreferrer"&gt;GHSA-vc2v-76pw-4v95&lt;/a&gt; / CVE-2026-87776 rates this High (CVSS 7.5, AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H). Impact is availability only. npm published 1.8.2 the same day as the advisory (2026-09-11). Weekly downloads for &lt;code&gt;compression&lt;/code&gt; sit around 30 million, so most Express and Connect stacks that enable response compression are on the blast radius.&lt;/p&gt;

&lt;p&gt;The 1.8.2 patch does three things the GHSA blurb does not spell out. It adds a &lt;code&gt;close&lt;/code&gt; listener on the response &lt;em&gt;before&lt;/em&gt; &lt;code&gt;onHeaders&lt;/code&gt; runs, so a disconnect that lands before the zlib stream exists is still recorded. It releases that stream through the &lt;code&gt;destroy&lt;/code&gt; package rather than calling &lt;code&gt;stream.destroy()&lt;/code&gt; alone, because the patch comment states that &lt;code&gt;destroy()&lt;/code&gt; by itself still leaks the zlib handle on some Node.js versions. And if the response already closed before the stream was created, it destroys the late stream immediately, nulls the reference, and falls back to the raw response so later writes do not keep a doomed compressor alive. HISTORY.md also notes a case-insensitive match for the &lt;code&gt;Cache-Control: no-transform&lt;/code&gt; skip, which is unrelated to the leak but ships in the same release.&lt;/p&gt;

&lt;p&gt;Affected: &lt;code&gt;compression&lt;/code&gt; npm &lt;code&gt;&amp;lt; 1.8.2&lt;/code&gt;. Fixed: &lt;code&gt;1.8.2&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who is not in scope
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  Apps that never mount &lt;code&gt;compression&lt;/code&gt; (or an Express/Connect stack that vendors it) and let a reverse proxy or CDN handle gzip/br instead.&lt;/li&gt;
&lt;li&gt;  Already-patched installs on &lt;code&gt;1.8.2&lt;/code&gt; or later.&lt;/li&gt;
&lt;li&gt;  Non-HTTP uses of zlib that do not go through this middleware.&lt;/li&gt;
&lt;li&gt;  Browsers and clients; this is a server-side leak on the response path.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to check
&lt;/h2&gt;

&lt;p&gt;From the app root:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;ls &lt;/span&gt;compression
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Any resolved version below &lt;code&gt;1.8.2&lt;/code&gt; is vulnerable. In lockfiles, search for the package entry and confirm the resolved version string. If you vendor a copy (Next.js and similar have historically vendored this middleware), check that tree the same way; a framework-level workaround does not replace upgrading the package you actually require.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to fix
&lt;/h2&gt;

&lt;p&gt;Upgrade compression to the patched release.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;compression@1.8.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pin or override transitive copies so every resolved path is &lt;code&gt;1.8.2&lt;/code&gt; or newer, then restart the process. The advisory lists no workaround other than the upgrade.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this is not
&lt;/h2&gt;

&lt;p&gt;This is not remote code execution, not credential theft, and not an auth bypass. A remote client that can open requests and disconnect early can drive memory exhaustion and crash the server. Damage stops at availability.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://github.com/expressjs/compression/security/advisories/GHSA-vc2v-76pw-4v95" rel="noopener noreferrer"&gt;GHSA-vc2v-76pw-4v95&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.cve.org/CVERecord?id=CVE-2026-87776" rel="noopener noreferrer"&gt;CVE-2026-87776&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/expressjs/compression/commit/0f9707417bd53d41a319fce8bdb80dfa08b435c8" rel="noopener noreferrer"&gt;compression 1.8.2 release commit&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://hol.org/guard/security/cves/CVE-2026-87776-compression-vulnerable-to-denial-of-service-via?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=blog_distribution&amp;amp;utm_content=cve-2026-87776-express-compression-zlib-abort-memory-dos" rel="noopener noreferrer"&gt;HOL Guard evidence pack for CVE-2026-87776&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cve</category>
      <category>compression</category>
      <category>express</category>
      <category>node</category>
    </item>
  </channel>
</rss>
