top of page

We Swept the Morning's Threat News and Found Nothing New. Then We Found Three Bugs, and All Three Were Ours.

Writer: Patrick Duggan
Patrick Duggan
54 minutes ago
5 min read

The morning sweep is supposed to find things. Today it found nothing, which turned out to be the interesting part.


Four stories were moving. CISA confirmed active exploitation of two PHP flaws, CVE-2026-109618 and CVE-2026-109619, and put them on the Known Exploited Vulnerabilities list on October 26 under Binding Operational Directive 26-04. Checkmarx published the MALFEX npm campaign, eight malicious packages, 40,767 downloads, delivering the Overlord RAT and an infostealer. Researchers showed that a malicious AGENTS.md file can steer Claude Code and Codex. And the ChainDrop wave of the Mini Shai-Hulud worm was still being written up.


We checked all four against our own corpus before writing a word, because the fastest way to publish something false is to assume a headline is news to you.



All four were already covered


We published on PHP2Shell on October 21, the day the fixes shipped, and again on October 23 when it picked up a Mirai payload. Twenty-seven attack indicators went into the feed. CISA listed the CVEs five days after our first post. That is not a detection scoop and we are not calling it one, because PHP disclosed the flaws themselves. It means a defender reading us had the patch list and the indicators five days before the federal must-patch order. Our own kev-lead measure says the same thing more broadly: of six CVEs added to KEV in the last seven days, five had a receipt in our corpus first, median five days ahead, and one did not.


The three MALFEX packages that were still installable, function-flag, function-color and cdn-img-fetch, all return a block verdict from our free package check, carrying OSV identifiers MAL-2026-17648, MAL-2026-17647 and MAL-2026-17320. We did not find those. OSV published them and we carry them, which is distribution value to anyone who does not run a commercial feed, not a discovery. Saying otherwise would be laundering somebody else's research under our name.


The AGENTS.md class we covered on October 26. ChainDrop we covered on August 6, including the part most of this week's coverage is only now reaching, that the persistence survives your cleanup because it lives in the agent's own config directories.


So: nothing new outside. Then we looked inward.



Our decision board printed "passed" for a trigger that had just fired




Our weekly report carries a sensor table and, below it, a board of decision gates. On this week's report the sensor named meili_queue read breach. Three rows down, the gate it feeds, the one that controls whether we split our search index across two instances for about $230 a month, read passed.


Both were computed correctly. For a gate marked as a trigger, passed was defined as "the condition fired." It was documented in the source and covered by a unit test. It was also, on a board where every other row's passed means the bar was met and all is well, the exact opposite of what a human reads.


That is a homonym in a status vocabulary, and a status vocabulary is an interface.



The part that was a real bug


Chasing that, we found the layer underneath. The function that turns the gate board into a single verdict for our automated reviewer returned FAIL when any gate had failed, DRIFT when any gate was at risk or unmeasurable, and PASS for everything else. Everything else included fired.


So a trigger firing, which means a decision is now due, made the entire decision board report green to the agent that reads it at the start of every session. Not a wrong number. A correct number, routed to the optimistic default.


Trigger gates now return fired, fired judges as DRIFT, and the board renders it in red. Forty-eight unit tests pass. The fix is committed and ships with our next image, so as of this writing it is in the repository and not yet in production, which is the sort of distinction we would want stated if you were reading our report instead of writing it.



What we are not fixing yet, and are naming anyway


One row below all this, a sensor called unchanged_upserts reads ok, with a value of 0.979.


What that number measures is that 97.9 percent of the writes we make into our indicator index change nothing at all. The write is accepted, the document is re-embedded, the queue absorbs the cost, and the record is identical to the one already there. That is the reason the queue is backed up. The remedy the board prescribes is more hardware.


More hardware does not fix a system that is failing on writes that change nothing. The real fix is to move a "still listed" marker out of the embedded index, and it is open work, not shipped work. The sensor is green because the question it was built to answer, go or no-go on diff-before-write, has an answer. It reads as healthy. We are leaving it in the report as it is until the underlying work lands, and naming it here so that nobody, including us, mistakes the color for the condition.



The third one had nothing to do with any of that


While looking at why first-time visitors bounce off our homepage, we read the served HTML instead of the page. In the footer, a link displaying our own contact address pointed at a template placeholder left over from the site builder's default. The visible text said one thing. The link target said another. Anyone who clicked it sent mail nowhere.


We have instruments that check for invisible Unicode in config files, for malicious packages, for drift in the code embedded in our own page head. Not one of them reads the destination of a link. The fix took thirty seconds in the editor. Finding it took reading an artifact nobody had reason to read, and verifying it meant fetching the live page afterward and counting that the placeholder went from one occurrence to zero.


There is a trap next door, which we walked into for about a minute. Grepping the page for mail links also matches JavaScript regular expressions that contain them, so two of our own analytics patterns looked briefly like two more broken links. They were not. We checked before we wrote.



What the day was actually about


Three defects, all ours, and the two serious ones were instruments reporting success. That is not a coincidence or a bad day. It is the shape this work takes once your outward-facing checks are decent: the adversary has other people watching too, and nobody but you is going to ask whether your own green lights are telling the truth.


A word that means two opposite things on one page. A default that routes an unrecognized verdict to the reassuring answer. A link whose text and target disagree. None of these is a miscalculation. Every one of them is a correct answer to a question slightly beside the one that mattered, and that kind of answer stays correct forever, which is exactly why it survives.


Measured October 28, 2026 against our own signed report, our repository and our live pages. First-party. We cap ourselves at 95 percent confidence, because something is always wrong, and on the evidence above it is usually something of ours.




Every indicator in this post is in the feed. Free.

1.58M+ IOCs, STIX 2.1 / TAXII, 88% novel vs ThreatFox, exploited-CVE leads ahead of CISA. No credit card — a free API key in 30 seconds, and you can audit every claim above against the live endpoints.


Comments

Rated 0 out of 5 stars.
No ratings yet

Add a rating
bottom of page