<rss version="2.0">
  <channel>
    <title>Blog on Experience Digest</title>
    <link>https://experiencedigest.org/blog/</link>
    <description></description>
    
    <language>en</language>
    
    <lastBuildDate>Tue, 23 Jun 2026 00:00:00 +0000</lastBuildDate>
    
    <item>
      <title>Two Patch Cycles, Same Cracks: What Commerce&#39;s 2026 CVE Pattern Is Telling You</title>
      <link>https://experiencedigest.org/blog/2026-06-23-two-patch-cycles-same-cracks/</link>
      <pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate>
      <guid>https://experiencedigest.org/blog/2026-06-23-two-patch-cycles-same-cracks/</guid>
      <description>&lt;p&gt;Adobe&amp;rsquo;s May 2026 Commerce bulletin (&lt;a href=&#34;https://helpx.adobe.com/security/products/magento/apsb26-49.html&#34;&gt;APSB26-49&lt;/a&gt;) dropped 14 CVEs on May 12. March&amp;rsquo;s (&lt;a href=&#34;https://helpx.adobe.com/security/products/magento/apsb26-05.html&#34;&gt;APSB26-05&lt;/a&gt;) was lighter by volume but not by type. Scroll through both and the same vulnerability categories keep surfacing: Incorrect Authorization and Stored XSS, bulletin after bulletin. Not the same bugs — different entry points, different CVSS scores, different reporters — but the same &lt;em&gt;kind&lt;/em&gt; of bug. That&amp;rsquo;s the pattern worth paying attention to.&lt;/p&gt;
&lt;p&gt;APSB26-05 delivered four critical Stored XSS findings (&lt;a href=&#34;https://nvd.nist.gov/vuln/detail/CVE-2026-21361&#34;&gt;CVE-2026-21361&lt;/a&gt;, &lt;a href=&#34;https://nvd.nist.gov/vuln/detail/CVE-2026-21284&#34;&gt;CVE-2026-21284&lt;/a&gt;, &lt;a href=&#34;https://nvd.nist.gov/vuln/detail/CVE-2026-21290&#34;&gt;CVE-2026-21290&lt;/a&gt;, &lt;a href=&#34;https://nvd.nist.gov/vuln/detail/CVE-2026-21311&#34;&gt;CVE-2026-21311&lt;/a&gt;), all leading to privilege escalation, alongside three Incorrect Authorization findings (&lt;a href=&#34;https://nvd.nist.gov/vuln/detail/CVE-2026-21289&#34;&gt;CVE-2026-21289&lt;/a&gt;, &lt;a href=&#34;https://nvd.nist.gov/vuln/detail/CVE-2026-21309&#34;&gt;CVE-2026-21309&lt;/a&gt;, &lt;a href=&#34;https://nvd.nist.gov/vuln/detail/CVE-2026-21285&#34;&gt;CVE-2026-21285&lt;/a&gt;). APSB26-49 reprised both categories: two more Incorrect Authorization auth bypasses (&lt;a href=&#34;https://nvd.nist.gov/vuln/detail/CVE-2026-34645&#34;&gt;CVE-2026-34645&lt;/a&gt;, &lt;a href=&#34;https://nvd.nist.gov/vuln/detail/CVE-2026-34646&#34;&gt;CVE-2026-34646&lt;/a&gt;) and a critical Stored XSS reaching code execution (&lt;a href=&#34;https://nvd.nist.gov/vuln/detail/CVE-2026-34686&#34;&gt;CVE-2026-34686&lt;/a&gt;, CVSS 8.7).&lt;/p&gt;
&lt;p&gt;Incorrect Authorization at this frequency points at access control logic that&amp;rsquo;s distributed across the codebase — the kind of architecture where a new endpoint or module can introduce a gap without touching anything that looks like a security check. Stored XSS recurring across bulletin cycles suggests input handling that&amp;rsquo;s inconsistent at the point of persistence. Two different root causes, both showing up across two major patch cycles. That&amp;rsquo;s structural, not bad luck.&lt;/p&gt;
&lt;h2 id=&#34;the-dos-surface-is-expanding&#34;&gt;The DoS surface is expanding&lt;/h2&gt;
&lt;p&gt;APSB26-49 added something APSB26-05 didn&amp;rsquo;t: a cluster of five unauthenticated resource exhaustion vectors, all critical, all requiring no authentication and no admin access.&lt;/p&gt;
&lt;p&gt;Four are independent CWE-400 findings (&lt;a href=&#34;https://nvd.nist.gov/vuln/detail/CVE-2026-34648&#34;&gt;CVE-2026-34648&lt;/a&gt;, &lt;a href=&#34;https://nvd.nist.gov/vuln/detail/CVE-2026-34649&#34;&gt;CVE-2026-34649&lt;/a&gt;, &lt;a href=&#34;https://nvd.nist.gov/vuln/detail/CVE-2026-34650&#34;&gt;CVE-2026-34650&lt;/a&gt;, &lt;a href=&#34;https://nvd.nist.gov/vuln/detail/CVE-2026-34651&#34;&gt;CVE-2026-34651&lt;/a&gt;), all CVSS 7.5. The fifth (&lt;a href=&#34;https://nvd.nist.gov/vuln/detail/CVE-2026-34652&#34;&gt;CVE-2026-34652&lt;/a&gt;) comes through a third-party component dependency at the same score.&lt;/p&gt;
&lt;p&gt;That fifth one changes the calculus. A DoS vector introduced through a dependency means the attack surface includes code the Commerce core team didn&amp;rsquo;t write and Adobe&amp;rsquo;s bulletin doesn&amp;rsquo;t fully cover. If your Commerce install carries Composer packages beyond the default set — and it almost certainly does — the exposure footprint for resource exhaustion is larger than any single security bulletin accounts for. Third-party patch cadence is your problem to manage, not Adobe&amp;rsquo;s.&lt;/p&gt;
&lt;h2 id=&#34;what-six-bulletins-in-fourteen-months-actually-costs&#34;&gt;What six bulletins in fourteen months actually costs&lt;/h2&gt;
&lt;p&gt;Adobe has shipped more than six Commerce security bulletins since April 2025. If your patching workflow is &amp;ldquo;engineer reads the bulletin, schedules a Composer update, tests in staging, ships in a two-week window&amp;rdquo; — the math doesn&amp;rsquo;t close. You&amp;rsquo;re structurally behind before you start, and with a CVSS 8.7 path traversal (&lt;a href=&#34;https://nvd.nist.gov/vuln/detail/CVE-2026-34653&#34;&gt;CVE-2026-34653&lt;/a&gt;) and a CVSS 8.7 Stored XSS in the latest bulletin, the cost of that lag is non-trivial.&lt;/p&gt;
&lt;p&gt;Shops keeping pace have automated the Composer lockfile update step: a scheduled CI job opens a branch the moment a security release hits Packagist, runs the test suite against it, and puts a PR in front of someone who can approve in hours, not weeks. Security patches shouldn&amp;rsquo;t require scheduling. When they do, maintenance overhead compounds with every bulletin.&lt;/p&gt;
&lt;h2 id=&#34;what-to-do&#34;&gt;What to do&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Merchants:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Check your Commerce version against the &lt;a href=&#34;https://helpx.adobe.com/security/products/magento/apsb26-49.html&#34;&gt;APSB26-49 affected versions table&lt;/a&gt;. If you&amp;rsquo;re on 2.4.8-p4 or earlier (or the equivalent patch on your supported line), the full CVE set above is open on your installation.&lt;/li&gt;
&lt;li&gt;Treat the two CVSS 8.7 findings (CVE-2026-34653, CVE-2026-34686) as high-priority — these aren&amp;rsquo;t &amp;ldquo;next maintenance window&amp;rdquo; candidates.&lt;/li&gt;
&lt;li&gt;Audit your third-party Composer dependency exposure separately from Adobe&amp;rsquo;s bulletins. CVE-2026-34652 is the model case for why.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Agencies and integrators:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Automate Composer security patch delivery across your client fleet — a bot that opens a branch on new Packagist security releases, runs tests, and queues a PR for sign-off. The bulletin frequency makes manual scheduling untenable at scale.&lt;/li&gt;
&lt;li&gt;Audit your client installs for version compliance before the next bulletin drops. Six bulletins in fourteen months means you&amp;rsquo;re likely carrying at least one unpatched cycle on slower-moving accounts.&lt;/li&gt;
&lt;li&gt;Patch complexity varies: most of APSB26-49 clears with a standard Composer update and cache flush. CVSS 8.7 findings warrant an explicit QA gate before production. Know which bulletins need staging validation and which don&amp;rsquo;t — blanket &amp;ldquo;treat every patch the same&amp;rdquo; policies are why teams fall behind.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Sources: &lt;a href=&#34;https://helpx.adobe.com/security/products/magento/apsb26-49.html&#34;&gt;APSB26-49&lt;/a&gt; (Adobe, May 12, 2026) · &lt;a href=&#34;https://helpx.adobe.com/security/products/magento/apsb26-05.html&#34;&gt;APSB26-05&lt;/a&gt; (Adobe, March 10, 2026)&lt;/em&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>APSB26-56: thirty-plus XSS findings in one AEM bulletin — what the batch tells you</title>
      <link>https://experiencedigest.org/blog/2026-06-10-aem-xss-apsb26-56/</link>
      <pubDate>Wed, 10 Jun 2026 00:00:00 +0000</pubDate>
      <guid>https://experiencedigest.org/blog/2026-06-10-aem-xss-apsb26-56/</guid>
      <description>&lt;p&gt;Adobe published APSB26-56 on June 9, 2026 — a security update for Adobe Experience Manager 6.5 and AEM as a Cloud Service. The advisory contains at least 36 cross-site scripting vulnerabilities, the overwhelming majority of them stored XSS, each carrying CVSS 5.4.&lt;/p&gt;
&lt;p&gt;That number matters more than the severity score.&lt;/p&gt;
&lt;h2 id=&#34;what-the-bulletin-contains&#34;&gt;What the bulletin contains&lt;/h2&gt;
&lt;p&gt;Every finding in APSB26-56 shares the same profile: cross-site scripting via improper output encoding, low-privilege exploitation path (authenticated author access required), CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N.&lt;/p&gt;
&lt;p&gt;Confirmed stored XSS CVEs (27): CVE-2026-47936, CVE-2026-47939, CVE-2026-47941, CVE-2026-47942, CVE-2026-47943, CVE-2026-47944, CVE-2026-47945, CVE-2026-47948, CVE-2026-47949, CVE-2026-47950, CVE-2026-47951, CVE-2026-47953, CVE-2026-47954, CVE-2026-47956, CVE-2026-47957, CVE-2026-47958, CVE-2026-47962, CVE-2026-47966, CVE-2026-47970, CVE-2026-47972, CVE-2026-47973, CVE-2026-47974, CVE-2026-47975, CVE-2026-47977, CVE-2026-47978, CVE-2026-47980, CVE-2026-47981&lt;/p&gt;
&lt;p&gt;Confirmed DOM-based XSS CVEs (9): CVE-2026-47935, CVE-2026-47946, CVE-2026-47947, CVE-2026-47982, CVE-2026-47983, CVE-2026-47985, CVE-2026-47986, CVE-2026-47987, CVE-2026-47989&lt;/p&gt;
&lt;p&gt;The bulletin&amp;rsquo;s full CVE list is longer than what was enumerated here — the advisory page truncates on initial load. The 36 above are confirmed; the actual total is likely higher.&lt;/p&gt;
&lt;p&gt;The exploitation surface: AEM content authoring interfaces. An author-level account, or an author who pastes content from an untrusted source, can plant a payload that executes in any session that renders it. No administrative access required.&lt;/p&gt;
&lt;p&gt;CVSS 5.4 looks modest against a remote code execution finding, but the effective blast radius is wider in practice. Content editors typically operate the most public-facing interfaces in an AEM deployment. A stored XSS in that context can reach site visitors, not just other authenticated users.&lt;/p&gt;
&lt;h2 id=&#34;why-a-batch-of-36-says-more-than-any-individual-cve&#34;&gt;Why a batch of 36 says more than any individual CVE&lt;/h2&gt;
&lt;p&gt;A single stored XSS finding is noise. A batch of 36 from the same systematic audit is signal.&lt;/p&gt;
&lt;p&gt;When Adobe identifies this many findings in a single bulletin, it indicates a coordinated security review of AEM&amp;rsquo;s component layer — not routine vulnerability triage. The review already happened. The bugs that would surface in an equivalent review of your current version have already been found; you either have the fix or you are running exposed.&lt;/p&gt;
&lt;p&gt;There is a specific implication for teams on earlier service packs: the vulnerabilities that this audit surfaced exist across the prior service pack tree until patched. A team on 6.5.22 or 6.5.23 carries all 36 of these plus whatever the prior audit cycles fixed that they have not yet applied.&lt;/p&gt;
&lt;p&gt;Batch disclosure is a trailing indicator of systematic review. APSB26-56&amp;rsquo;s 36 findings represent one audit cycle. The next cycle will produce another bulletin.&lt;/p&gt;
&lt;h2 id=&#34;the-upgrade-cadence-argument&#34;&gt;The upgrade cadence argument&lt;/h2&gt;
&lt;p&gt;APSB26-56 is addressed in AEM 6.5.24 and AEM as a Cloud Service (auto-applied). This is not an emergency hotfix — it is a service pack release. The fix has been available since June 9.&lt;/p&gt;
&lt;p&gt;Teams running deferred upgrade cycles are making a specific trade: testing overhead of service pack validation against ongoing CVE exposure. For a single-CVE bulletin, that trade can be defensible. For a bulletin with 36 XSS findings against the author interface, the calculus is different.&lt;/p&gt;
&lt;p&gt;Some specific implications:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If your cycle puts you more than one service pack behind, you are carrying CVEs from at least two bulletin cycles.&lt;/li&gt;
&lt;li&gt;AEM 6.5.x ships quarterly service packs. A &amp;ldquo;wait for the next maintenance window&amp;rdquo; that stretches to six months is two full bulletin cycles of exposure.&lt;/li&gt;
&lt;li&gt;Each skipped service pack is not just the CVEs in that bulletin — it is that bulletin plus the systematic audit that produced it, applied to whichever component class Adobe reviewed next.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Upgrade cadence is not a development operations preference. It is a security posture decision with cumulative exposure in both directions.&lt;/p&gt;
&lt;h2 id=&#34;what-to-do&#34;&gt;What to do&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Check your version.&lt;/strong&gt; AEM 6.5.24 addresses APSB26-56. Confirm your service pack level against the bulletin before your next maintenance window.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prioritize 6.5.24 if you are on 6.5.22 or earlier.&lt;/strong&gt; You are carrying these 36 CVEs plus the delta from any skipped service packs between your current version and 6.5.24.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Review your author trust model.&lt;/strong&gt; Output encoding in custom components is defense-in-depth that reduces stored XSS surface regardless of patch level. If your authors routinely paste content from external sources, that review is worth running independently of your service pack schedule.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Track service pack cadence as a security metric.&lt;/strong&gt; How many service packs you are behind is a meaningful proxy for unpatched CVE exposure, particularly when Adobe&amp;rsquo;s systematic audits are producing batches of this size.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The 36 CVEs will be in your scanner by now. The batch pattern — a systematic component audit producing 36 findings across a single bulletin — is the signal worth acting on.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Sources: &lt;a href=&#34;https://helpx.adobe.com/security/products/experience-manager/apsb26-56.html&#34;&gt;APSB26-56 — Security update available for Adobe Experience Manager&lt;/a&gt; (Adobe, June 9, 2026)&lt;/em&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Before the Next Wave: What Magento Shops Must Do After the Composer Token Leak</title>
      <link>https://experiencedigest.org/blog/2026-06-10-composer-github-token-leak/</link>
      <pubDate>Wed, 10 Jun 2026 00:00:00 +0000</pubDate>
      <guid>https://experiencedigest.org/blog/2026-06-10-composer-github-token-leak/</guid>
      <description>&lt;p&gt;On May 12, 2026, the PHP ecosystem had a near-miss that deserves more attention than it received. The &lt;a href=&#34;https://github.com/graycoreio/github-actions-magento2/discussions/261&#34;&gt;post-mortem from the graycoreio maintainer&lt;/a&gt; — who runs the canonical GitHub Actions suite for Magento and Mage-OS — is worth reading in full. Here is the operational summary for Commerce shops.&lt;/p&gt;
&lt;h2 id=&#34;what-happened&#34;&gt;What happened&lt;/h2&gt;
&lt;p&gt;GitHub began rolling out a new format for App installation tokens. The new format includes characters (&lt;code&gt;-&lt;/code&gt;) that Composer&amp;rsquo;s existing token validator rejected. When Composer threw the validation exception, it included the literal token value in the error message. Symfony Console rendered that message to stderr before the Actions runner could mask it — bypassing the secret masker&amp;rsquo;s substring match.&lt;/p&gt;
&lt;p&gt;For roughly 14 hours (2026-05-12 ~22:00 UTC to 2026-05-13 ~14:30 UTC), any workflow that ran &lt;code&gt;composer install&lt;/code&gt; after &lt;code&gt;shivammathur/setup-php&lt;/code&gt; on a &lt;code&gt;push&lt;/code&gt;, &lt;code&gt;pull_request_target&lt;/code&gt;, or &lt;code&gt;schedule&lt;/code&gt; trigger had its &lt;code&gt;GITHUB_TOKEN&lt;/code&gt; printed in plaintext to a world-readable Actions log.&lt;/p&gt;
&lt;p&gt;The typical &lt;code&gt;GITHUB_TOKEN&lt;/code&gt; on a push workflow carries &lt;code&gt;contents: write&lt;/code&gt; by default. That is enough to push commits and tags to the repo it came from.&lt;/p&gt;
&lt;h2 id=&#34;why-magento-shops-specifically-should-care&#34;&gt;Why Magento shops specifically should care&lt;/h2&gt;
&lt;p&gt;The graycoreio maintainer caught this while working on Magento 2.4.9 release support. His report named the repos where failures were visible during the window: &lt;code&gt;composer/composer&lt;/code&gt; itself, &lt;code&gt;laravel/framework&lt;/code&gt;, &lt;code&gt;sylius&lt;/code&gt;, &lt;code&gt;woocommerce&lt;/code&gt;, and others.&lt;/p&gt;
&lt;p&gt;For Magento deployments, the supply chain path is direct: Magento and Mage-OS are Composer projects. Packagist polls GitHub for new tags and publishes them automatically. A successful exfil-and-push against any sufficiently popular Composer package resolves as remote code execution on every store that runs &lt;code&gt;composer install&lt;/code&gt; before the rollback.&lt;/p&gt;
&lt;p&gt;The maintainer has a working proof of concept: a stolen token can push to main in under a second with a polling setup. The window is narrow, but it is real.&lt;/p&gt;
&lt;h2 id=&#34;this-is-not-over&#34;&gt;This is not over&lt;/h2&gt;
&lt;p&gt;Composer shipped patched releases (2.9.8 / 2.2.28 / 1.10.28) and GitHub paused the rollout. GitHub will resume the format change. The fix has to be in place before the next wave.&lt;/p&gt;
&lt;h2 id=&#34;what-to-do&#34;&gt;What to do&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Bump Composer in CI.&lt;/strong&gt; If your workflows pin Composer — &lt;code&gt;tools: composer:v2.8.1&lt;/code&gt; in setup-php, or a hardcoded version anywhere — unpin it or bump to 2.9.8 / 2.2.28 / 1.10.28. Unpatched Composer is the entire attack surface here.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Add an explicit &lt;code&gt;permissions:&lt;/code&gt; block.&lt;/strong&gt; Workflows without one inherit the legacy permissive default (&lt;code&gt;contents: write&lt;/code&gt;). Add &lt;code&gt;permissions: contents: read&lt;/code&gt; at the top of every workflow that does not need write access. Most CI jobs do not.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Protect your tags.&lt;/strong&gt; The practical attack vector is pushing a tag to trigger a Packagist release. Enable GitHub tag protection rules on your repos. Branch protection alone does not cover tags — that distinction matters here.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sweep your logs for the window.&lt;/strong&gt; Look at failed runs between 2026-05-12 22:00 UTC and 2026-05-13 14:30 UTC. If you see a &lt;code&gt;ghs_…&lt;/code&gt; string in any rendered output, your token was exposed. Then run:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;git log --since&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;2026-05-12T22:00Z&amp;#39;&lt;/span&gt; --until&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;2026-05-13T14:30Z&amp;#39;&lt;/span&gt; --all
git tag --sort&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;creatordate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Check both for anything you do not recognize.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Review failure-upload steps.&lt;/strong&gt; If you have &lt;code&gt;actions/upload-artifact&lt;/code&gt; on &lt;code&gt;if: failure()&lt;/code&gt; steps, those extend the live-token window while the upload runs — for large test fixtures this can be minutes, not seconds. Consider whether those steps need the token in scope, or whether the artifact upload can be moved outside the token&amp;rsquo;s lifetime.&lt;/p&gt;
&lt;h2 id=&#34;the-broader-lesson&#34;&gt;The broader lesson&lt;/h2&gt;
&lt;p&gt;The person who caught this describes himself as a small fish. He caught it because he was actively working on Magento 2.4.9 support, noticed intermittent CI failures that did not match any change he had made, and dug in. His immediate actions — disabling actions org-wide, reaching out to Laravel and Mage-OS Discord, filing the Composer advisory — almost certainly kept this from being exploited.&lt;/p&gt;
&lt;p&gt;The ecosystem&amp;rsquo;s defense was accidental: Composer fails loudly, tokens are repo-scoped and short-lived, the rollout was gradual. None of that is engineered defense-in-depth. The checklist above is the engineered version. With the next rollout wave coming, there is no reason to wait.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Sources: &lt;a href=&#34;https://github.com/graycoreio/github-actions-magento2/discussions/261&#34;&gt;graycoreio/github-actions-magento2 #261&lt;/a&gt; · &lt;a href=&#34;https://github.com/composer/composer/security/advisories/GHSA-f9f8-rm49-7jv2&#34;&gt;CVE-2026-45793 / GHSA-f9f8-rm49-7jv2&lt;/a&gt; · &lt;a href=&#34;https://blog.packagist.com/composer-2-9-8-and-2-2-28-fix-github-actions-token-disclosure-in-error-messages/&#34;&gt;Composer 2.9.8 release notes&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>GorgonAgora: Inside the 4,800-Storefront Checkout Skimming Machine</title>
      <link>https://experiencedigest.org/blog/2026-06-03-gorgonagora-checkout-skimming/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>https://experiencedigest.org/blog/2026-06-03-gorgonagora-checkout-skimming/</guid>
      <description>&lt;p&gt;Security researcher Hunter Heaivilin has been mapping a skimming operation called GorgonAgora since August 2025. The dataset he handed to Sansec confirmed 4,880 fake storefronts — and urlscan.io&amp;rsquo;s CSS fingerprint matching suggests the real number is already above 6,000.&lt;/p&gt;
&lt;p&gt;The attack pattern differs from classic magecart. GorgonAgora doesn&amp;rsquo;t touch your store. The operator scraped product catalogs from real Shopify storefronts belonging to hundreds of brands — Starbucks, Nike, Ford, Sony, Disney, Lego, DJI and more — and rebuilt each one as a lookalike on a .shop domain. Every store runs Medusa.js as its commerce backend. Every checkout loads the same SDK: &lt;code&gt;payment-vanilla.iife.js&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;how-paymentvanilla-works&#34;&gt;How PaymentVanilla works&lt;/h2&gt;
&lt;p&gt;When a shopper reaches checkout, the SDK injects a pixel-perfect fake Stripe iframe. The real Stripe is never involved. Card data flows to a WebSocket endpoint at an AlexHost server in Moldova, encrypted with AES-256-GCM. If the victim&amp;rsquo;s bank returns a 3DS challenge, the operator relays it back through the fake iframe. The transaction completes. The shopper believes they bought from a real brand.&lt;/p&gt;
&lt;p&gt;The 3DS relay is what makes this particularly effective — victims have no immediate signal that anything went wrong.&lt;/p&gt;
&lt;h2 id=&#34;two-generations-one-fingerprint&#34;&gt;Two generations, one fingerprint&lt;/h2&gt;
&lt;p&gt;The operator made one structural upgrade in late March 2026, switching from a single shared Medusa database (~339 stores, one publishable API key fronting 544 brand catalogs) to individual Medusa instances per storefront (~4,500+ stores). The shared-key enumeration hole is gone. Everything else is unchanged: same CSS bundle (&lt;code&gt;d482fd41f7f1f379.css&lt;/code&gt;), same JS chunk, same skimmer SDK, same C2. The network is trivially fingerprintable despite the backend refactor.&lt;/p&gt;
&lt;h2 id=&#34;what-to-do&#34;&gt;What to do&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;For brand owners:&lt;/strong&gt; Search urlscan.io using &lt;code&gt;filename:d482fd41f7f1f379.css&lt;/code&gt; to find storefronts cloning your catalog. The operator scrapes from real Shopify stores, so trademark and DMCA takedowns typically work fast once you identify a clone. Set up ongoing brand monitoring for your domain variants — the &lt;code&gt;.shop&lt;/code&gt; TLD is the current pattern, but it&amp;rsquo;s a template.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;For shoppers:&lt;/strong&gt; If you transacted on a &lt;code&gt;.shop&lt;/code&gt; domain in the IOC list, treat the card as compromised and request a replacement.&lt;/p&gt;
&lt;p&gt;Full technical write-up including C2 IPs, SDK hashes, and the complete sample domain list: &lt;a href=&#34;https://sansec.io/research/gorgonagora-fake-storefront-skimming-network&#34;&gt;sansec.io/research/gorgonagora-fake-storefront-skimming-network&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The Perforce Driver You Never Knew You Had: Composer CVE-2026-40261 and CVE-2026-40176</title>
      <link>https://experiencedigest.org/blog/2026-05-23-composer-perforce-command-injection/</link>
      <pubDate>Sat, 23 May 2026 10:00:00 -0500</pubDate>
      <guid>https://experiencedigest.org/blog/2026-05-23-composer-perforce-command-injection/</guid>
      <description>&lt;p&gt;Update Composer to 2.9.6 or 2.2.27 LTS now. If that sentence is enough, you&amp;rsquo;re done. If you want to understand why this one is worth a closer look, keep reading.&lt;/p&gt;
&lt;p&gt;Background: the Composer maintainers published &lt;a href=&#34;https://blog.packagist.com/composer-2-9-6-perforce-driver-command-injection-vulnerabilities/&#34;&gt;their own writeup of these advisories&lt;/a&gt; on the Packagist blog. The technical details and the registry-level mitigations described below come from that post; this piece is the operator&amp;rsquo;s read for commerce teams.&lt;/p&gt;
&lt;h2 id=&#34;quick-refresher-composer-drivers-and-why-perforce-is-in-there&#34;&gt;Quick Refresher: Composer, Drivers, and Why Perforce Is in There&lt;/h2&gt;
&lt;p&gt;If you don&amp;rsquo;t live in PHP-land daily, this advisory reads as opaque, so a thirty-second primer.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://getcomposer.org/&#34;&gt;Composer&lt;/a&gt; is the dependency manager every modern PHP project uses. For Magento and Adobe Commerce specifically, it is how the core platform itself ships and how every module — first-party, third-party, your own internal libraries — gets installed and updated. When a developer runs &lt;code&gt;composer install&lt;/code&gt; on a fresh Magento checkout, Composer reads &lt;code&gt;composer.json&lt;/code&gt;, resolves the dependency graph, downloads each package, and assembles &lt;code&gt;vendor/&lt;/code&gt;. When CI deploys a release, it runs the same command. There is no Magento install today that does not run Composer many times a day.&lt;/p&gt;
&lt;p&gt;A &lt;code&gt;composer.json&lt;/code&gt; lists each dependency along with where to fetch it from. Most packages come from &lt;a href=&#34;https://packagist.org/&#34;&gt;Packagist&lt;/a&gt; (the public PHP registry) or its commercial sibling &lt;a href=&#34;https://packagist.com/&#34;&gt;Private Packagist&lt;/a&gt;. But you can also point Composer directly at a source-control repository — a git URL, a mercurial repo, a subversion checkout, or a &lt;a href=&#34;https://www.perforce.com/products/helix-core&#34;&gt;Perforce&lt;/a&gt; depot. To do that, you declare a repository in &lt;code&gt;composer.json&lt;/code&gt; with a &lt;code&gt;type:&lt;/code&gt; field naming which version-control system to use. Composer ships with a &lt;strong&gt;VCS driver&lt;/strong&gt; for each supported type — &lt;code&gt;git&lt;/code&gt;, &lt;code&gt;svn&lt;/code&gt;, &lt;code&gt;hg&lt;/code&gt;, &lt;code&gt;fossil&lt;/code&gt;, &lt;code&gt;perforce&lt;/code&gt; — that knows how to clone, list versions, and fetch source from that system.&lt;/p&gt;
&lt;p&gt;The Perforce driver is one of those bundled drivers. It exists because Perforce is the dominant version-control system in game studios, large enterprises with legacy commercial codebases, and some sectors of finance and manufacturing — places where PHP shops occasionally need to pull a package from a Perforce depot. The driver is shipped with Composer by default. &lt;strong&gt;It loads regardless of whether you have ever configured a Perforce repository.&lt;/strong&gt; That last point is the whole story of this CVE.&lt;/p&gt;
&lt;h2 id=&#34;the-perforce-driver-is-loaded-whether-you-use-it-or-not&#34;&gt;The Perforce Driver Is Loaded Whether You Use It or Not&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/composer/composer/security/advisories/GHSA-gqw4-4w2p-838q&#34;&gt;CVE-2026-40261&lt;/a&gt; and &lt;a href=&#34;https://github.com/composer/composer/security/advisories/GHSA-wg36-wvj6-r67p&#34;&gt;CVE-2026-40176&lt;/a&gt; are both in Composer&amp;rsquo;s Perforce VCS driver - the code that handles repositories declared as perforce type in a composer.json. Neither requires Perforce to be installed. Both allow arbitrary command execution in the context of whatever runs composer install or composer update.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s the part the advisory buries in the third paragraph. Most Magento shops have never configured a Perforce repository and have no intention of doing so. That doesn&amp;rsquo;t matter. The vulnerable code path loads regardless, and an attacker-controlled composer.json or package metadata can reach it.&lt;/p&gt;
&lt;h2 id=&#34;two-different-attack-surfaces&#34;&gt;Two Different Attack Surfaces&lt;/h2&gt;
&lt;p&gt;CVE-2026-40176 requires the attacker to control the composer.json you&amp;rsquo;re actually running - the root manifest. The injected values are Perforce connection parameters (port, user, client) that get interpolated into shell commands without escaping. This is the local-project risk: if you&amp;rsquo;re running Composer commands on a project from an untrusted source, this fires.&lt;/p&gt;
&lt;p&gt;CVE-2026-40261 is the wider problem. It affects the syncCodeBase() method, which handles a source reference parameter that can come from &lt;em&gt;package metadata&lt;/em&gt; - not just the root composer.json. That means any Composer repository, including a compromised or malicious third-party repository, can serve package metadata that exploits this. You don&amp;rsquo;t have to touch the root manifest. You just have to install or update a dependency from source.&lt;/p&gt;
&lt;p&gt;The trigger condition: installing dev-prefixed versions (anything before 1.0.0, or packages with dev- prefix) defaults to &amp;ndash;prefer-source in Composer. Commerce agencies running Magento module development pipelines almost certainly have some dev-constraint packages in their dependency tree.&lt;/p&gt;
&lt;h2 id=&#34;what-this-means-for-a-magento-and-commerce-pipeline&#34;&gt;What This Means for a Magento and Commerce Pipeline&lt;/h2&gt;
&lt;p&gt;Enterprise commerce platforms run layered dependency graphs. The core is typically Magento/Adobe Commerce, which comes from the Magento Composer repository. Third-party modules come from a mix of Packagist, private repositories, and occasionally vendor-managed repos. Development workflows - module builds, staging deploys, CI pipelines - regularly operate with dev- constraints to pull HEAD on in-development extensions.&lt;/p&gt;
&lt;p&gt;In that environment, CVE-2026-40261 is not hypothetical. Any point in the supply chain where package metadata can be influenced - a compromised private repo, a package repository serving malicious metadata, a CI secret that got rotated too late - becomes a command injection entry point into your build environment. The build environment has access to credentials, cloud provider tokens, and staging infrastructure that production doesn&amp;rsquo;t expose directly.&lt;/p&gt;
&lt;p&gt;The patch notes say there&amp;rsquo;s no evidence of exploitation prior to publication. That&amp;rsquo;s the standard disclosure language and it&amp;rsquo;s worth taking at face value. It also doesn&amp;rsquo;t change the update calculus.&lt;/p&gt;
&lt;h2 id=&#34;packagist-and-private-packagist-already-moved&#34;&gt;Packagist and Private Packagist Already Moved&lt;/h2&gt;
&lt;p&gt;Packagist.org disabled Perforce source metadata on April 10, 2026 as a precaution. Private Packagist did the same. If your dependencies come exclusively from these sources and you&amp;rsquo;re not running &amp;ndash;prefer-source against anything that reaches Perforce metadata, your exposure was already mitigated at the registry layer.&lt;/p&gt;
&lt;p&gt;If you run Private Packagist Self-Hosted, the new release is dropping now - and you should scan your installation using the verification command the release announcement documents before relying on the registry-level mitigation.&lt;/p&gt;
&lt;h2 id=&#34;the-practical-calls&#34;&gt;The Practical Calls&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Run composer.phar self-update on every machine and CI runner that executes Composer commands. This includes local dev environments - dev machines are a vector, not just pipelines.&lt;/li&gt;
&lt;li&gt;If you can&amp;rsquo;t update immediately, &amp;ndash;prefer-dist in your installs eliminates the CVE-2026-40261 exposure by avoiding the source-fetch path. It&amp;rsquo;s a workaround, not a fix.&lt;/li&gt;
&lt;li&gt;For CVE-2026-40176: review any composer.json files you run Composer commands against and aren&amp;rsquo;t fully trust-anchored. If your dev workflow clones external projects and runs composer install on them without inspection, that&amp;rsquo;s a habit worth fixing regardless of this CVE.&lt;/li&gt;
&lt;li&gt;Audit your private Composer repositories for Perforce-type source declarations. These should not exist in commerce dependency graphs. If they do, understand why.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is a straightforward dependency update with a clear fix. The reason it&amp;rsquo;s worth editorial attention is the &amp;ldquo;doesn&amp;rsquo;t affect Perforce users&amp;rdquo; misread - the relevant audience here is every team running a PHP/Composer-based build pipeline, which in the commerce world is essentially everyone.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Three Signals from November: What the Bulletins Don&#39;t Say</title>
      <link>https://experiencedigest.org/blog/2025-11-26-three-signals-from-november/</link>
      <pubDate>Wed, 26 Nov 2025 09:00:00 -0500</pubDate>
      <guid>https://experiencedigest.org/blog/2025-11-26-three-signals-from-november/</guid>
      <description>&lt;p&gt;Three items from the November 2025 bulletin queue, taken individually, look like routine security hygiene. Together they tell a different story.&lt;/p&gt;
&lt;h2 id=&#34;the-setup-xurum-is-still-running-playbooks-from-2022&#34;&gt;The Setup: Xurum Is Still Running Playbooks from 2022&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&#34;https://www.akamai.com/blog/security-research/new-sophisticated-magento-campaign-xurum-webshell&#34;&gt;Xurum webshell campaign&lt;/a&gt; that Akamai documented isn&amp;rsquo;t new technique — it targets a known Magento vulnerability and deploys a sophisticated webshell that fingerprints server environment, exfiltrates payment data, and provides persistent shell access. What&amp;rsquo;s notable is that the campaign is &lt;em&gt;still running&lt;/em&gt;, which means:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A meaningful percentage of Magento installs are still unpatched against a well-documented attack chain.&lt;/li&gt;
&lt;li&gt;The attacker tooling has matured — Xurum has environment-awareness that older skimmer campaigns lacked.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The practical read for commerce ops teams: if you&amp;rsquo;re running a Magento instance and haven&amp;rsquo;t validated your patching posture against &lt;a href=&#34;https://www.akamai.com/blog/security-research/new-sophisticated-magento-campaign-xurum-webshell&#34;&gt;Akamai&amp;rsquo;s published indicators&lt;/a&gt;, do that before reading the rest of this.&lt;/p&gt;
&lt;h2 id=&#34;the-risk-that-patch-notes-dont-quantify-cve-2025-54236&#34;&gt;The Risk That Patch Notes Don&amp;rsquo;t Quantify: CVE-2025-54236&lt;/h2&gt;
&lt;p&gt;CVSS 9.1. Adobe Commerce. No user interaction required. Session takeover.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://helpx.adobe.com/security/products/magento/apsb25-88.html&#34;&gt;APSB25-88 advisory&lt;/a&gt; covers an improper input validation vulnerability affecting Adobe Commerce through 2.4.8-p2 and back to 2.4.4-p15. What the advisory doesn&amp;rsquo;t foreground: in a multi-store environment where admin sessions are long-lived (common in managed service deployments), &amp;ldquo;session takeover&amp;rdquo; means an attacker who can reach your admin panel URL has a path to full platform control without needing to know a single credential.&lt;/p&gt;
&lt;p&gt;The patch is available. The gap is the deployment window. A vulnerability that requires no user interaction closes fast in the wild once PoC code circulates — and for a CVSS 9.1 Adobe Commerce advisory, that window is short. If you&amp;rsquo;re on any affected version and your deployment pipeline adds days of testing overhead before applying security patches, that&amp;rsquo;s the thing worth fixing.&lt;/p&gt;
&lt;h2 id=&#34;the-sleeper-cve-2025-64174-and-admin-db-access-assumptions&#34;&gt;The Sleeper: CVE-2025-64174 and Admin DB Access Assumptions&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&#34;https://github.com/OpenMage/magento-lts/security/advisories/GHSA-qv78-c8hc-438r&#34;&gt;Magento-lts stored XSS&lt;/a&gt; (fixed in 20.16.0) requires an admin with direct database access or control over the admin notification feed source. That sounds narrow. It isn&amp;rsquo;t.&lt;/p&gt;
&lt;p&gt;In practice, multi-vendor commerce deployments frequently involve third-party integrations that touch the database directly — ETL pipelines, ERP connectors, PIM syncs. Any of those that write to notification tables or translation strings without sanitizing output are an injection vector that bypasses the application layer entirely. The &amp;ldquo;requires admin DB access&amp;rdquo; framing in the CVE undersells the real-world exposure surface.&lt;/p&gt;
&lt;h2 id=&#34;the-pattern&#34;&gt;The Pattern&lt;/h2&gt;
&lt;p&gt;All three of these point at the same underlying gap: Commerce platform security posture is often evaluated at the application layer (patches applied, WAF rules updated) while the actual attack surface extends further — into long-lived sessions, admin-adjacent integrations, and deployment lag. The bulletins report what&amp;rsquo;s been patched. The editorial job here is flagging what that means for how you run the platform.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s what this blog is for.&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>