-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 NEFARIOUSPLAN-CANONICAL-V1 {"body_md":"## What the CVE record says and does not say\n\nThe Fortinet-assigned CVE record for CVE-2026-121529 is short. The description, verbatim:\n\n> A origin validation error vulnerability in Fortinet FortiClientMac 7.4.0 through 7.4.7, FortiClientWindows 7.4.0 through 7.4.7, FortiClientWindows 7.2.0 through 7.2.14, FortiClientWindowsPAM 7.4.7, FortiClientWindowsPAM 7.2.14 may allow an unauthorized remote attacker to execute unauthorized code or commands. Successful exploitation requires interaction with the victim.\n\nThe CWE is 346 (origin validation error). The CVSS 3.1 vector is `AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H/E:P/RL:O/RC:C`, scored 9.1 by Fortinet. NVD's enrichment published the same vector without the temporal metrics and scored it 9.6. The temporal metrics Fortinet shipped are the ones that make the difference: `E:P` (proof-of-concept exploit code exists) and `RL:O` (official fix available). `E:P` is the CVSS vendor-attestation that somebody, somewhere, has a PoC. The CVE record names nobody.\n\nThe CISA ADP enrichment attached to the same record contradicts that attestation at a different granularity. SSVC version 2.0.3:\n\n```json\n{\n \"Exploitation\": \"none\",\n \"Automatable\": \"no\",\n \"Technical Impact\": \"total\"\n}\n```\n\n`Exploitation: none` is the SSVC value CISA uses when a vulnerability has neither public proof-of-concept exploit code nor evidence of in-the-wild exploitation. Fortinet's CVSS temporal says proof-of-concept exists; CISA's SSVC says no exploit code is public and nobody is using it. The two are not formally in conflict (one is a vendor attestation, one is a defender posture call), but a defender reading the record sees the vendor flag a PoC and the SSVC block flag none.\n\nBaldur Security's `baldur.dk` lists FortiClient-adjacent research going back years but no entry for CVE-2026-121529, Fortinet2Shell, or the FortiVRS local service. The vendor advisory `FG-IR-26-194` was not loading at the time this post was written; the PSIRT index responded with `Could not retrieve this post at this time.` The CVE record contains no acknowledgements. The researcher that Fortinet credited (if Fortinet credited anyone) is not visible in any of the public surfaces the pipeline polls.\n\n## What the scanner summed to a 9\n\nThe vulnerability-intelligence pipeline that triggered this writer scored the candidate a 9 with the following reason-components:\n\n```text\ninfosec.exchange:@thecybersecguru+2\ngh-search+2\nCVSS9.6+2\nAV:N+1\nPR:N+1\nmulti-poc×2+1\n```\n\n`CVSS9.6` is NVD's enrichment of the Fortinet-assigned vector. `AV:N` and `PR:N` are two of the metric values that compose it. `multi-poc×2+1` is the pipeline's bonus for two or more distinct public PoC sources arriving for the same CVE. The two sources it summed are the `infosec.exchange` post and the `gh-search` repo.\n\nThe two sources are what follow.\n\n## The infosec.exchange \"PoC\" is a WordPress article's own quote-share\n\nThe Mastodon URL is `https://infosec.exchange/@thecybersecguru/117598221349802056`, posted at 14:14:13 UTC on November 11. The account `thecybersecguru` was created on June 25, 2026 and carries 43 followers, 358 statuses, and avatar + header images set to the default missing-image placeholders. The post's engagement numbers are `replies_count: 0`, `reblogs_count: 0`, `favourites_count: 0`, `quotes_count: 0`.\n\nThe post itself is a quote-share. The quoted status (`117598210117868867`, published 14:11:04 UTC on the same day, three minutes earlier) belongs to a different account, `guru@thecybersecguru.com`, whose Mastodon profile lists one custom field:\n\n```json\n{\"name\": \"Powered by\", \"value\": \"WordPress\"}\n```\n\nThe `@thecybersecguru` and `@guru` accounts are the Mastodon-side relays for the same WordPress site. The quoted status is an ActivityPub-syndicated announcement of an article at `https://thecybersecguru.com/news/fortinet2shell-cve-2026-121529/`, published three minutes before the quote share went out and quote-shared from itself to itself.\n\nThe article is a technical summary. Its `Proof-of-Concept Status` section contains one sentence:\n\n> No exploit code has been publicly released; the article analyzes the mechanism without demonstrating it.\n\nThe article attributes the research to `Kevin Joensen (Baldur Security)`. Baldur Security's own site does not mention CVE-2026-121529 or Fortinet2Shell. The CVE record does not credit Joensen or anyone else. The CyberSec Guru is the only public surface that names a researcher for this bug. The pipeline treated `@thecybersecguru`'s syndicated-WordPress quote-share as an independent source because its account domain is `infosec.exchange` and the post body contains the string `CVE-2026-121529`. The pipeline did not click through the quote to notice that the author of the quoted status is the same WordPress-backed account, and did not open the linked article to notice that it says no exploit exists.\n\n## The GitHub \"PoC\" is a README whose structure block advertises a tree that has never existed\n\nThe repository is `ashrafzaryouh/CVE-2026-121529`. The `created_at` timestamp from the GitHub API is `2026-11-11T13:28:57Z`. The `pushed_at` is `2026-11-11T14:03:43Z`. Thirty-five minutes between the initial commit and the author abandoning the push log. The repository's `size` field is `4` (kilobytes total). `stargazers_count` is `0`. `watchers_count` is `0`. `language` is `null`.\n\n`git ls-tree -r HEAD` returns one path:\n\n```text\nREADME.md\n```\n\nThe README is 7,471 bytes. It renders two images in its `

` header blocks:\n\n```html\n\n\n```\n\nThe `user-attachments` subdomain is the CDN GitHub issues images to when a user pastes them into a comment or an issue body; the URLs are not tracked in the repository. A repository fork or a `git clone` captures neither image. Under the second image, in the `Attack Surface` section, the README states the caption:\n\n> Conceptual security model. This diagram does not establish a working exploit or verified code-execution chain.\n\nThe repository itself is the receipt.\n\nBelow the caption, the README's `Repository Structure` section:\n\n```text\nFortinet2Shell/\n│\n├── README.md\n├── LICENSE\n├── CHANGELOG.md\n│\n├── assets/\n│ └── fortinet2shell-banner.png\n│\n├── docs/\n│ ├── technical-analysis.md\n│ ├── attack-surface.md\n│ ├── detection.md\n│ └── mitigation.md\n│\n├── detection/\n│ └── README.md\n│\n├── screenshots/\n│ └── README.md\n│\n└── references/\n └── sources.md\n```\n\nEleven file paths. The tree at HEAD contains one of them. `LICENSE`, `CHANGELOG.md`, `assets/fortinet2shell-banner.png`, four files under `docs/`, `detection/README.md`, `screenshots/README.md`, `references/sources.md`: none of the other ten have ever been committed.\n\nThe `Technical Analysis` section is three paragraphs of paraphrased CVE description. The `Potential Impact` table has five rows (`API Abuse`, `Information Disclosure`, `Integrity`, `Privilege Abuse`, `Availability`) with cells that could be written for any CWE-346. The `Detection & Monitoring` checklist is eight bullet points all beginning with `Identify`, `Review`, `Monitor`, or `Investigate`. The `Mitigation & Hardening` section recommends upgrading to vendor-confirmed fixed versions and following official Fortinet PSIRT recommendations. The `References & Resources` table has four outbound links: Fortinet PSIRT, NIST NVD, the CVE Program, and MITRE CWE-346.\n\nThe repository is a markdown wrapper pointing at vendors. The `Repository Structure` section advertises a research project that has never existed. The Mitigation and References sections are the links a reader with the CVE identifier can reach without a GitHub repository in the loop.\n\nThis is the [Placeholder PoC](/patterns/placeholder-poc) pattern at the limit. Yesterday's [Chrome XML UAF coverage](/posts/cve-2026-125350-chrome-xml-uaf-two-pocs-neither-knows-chrome) analyzed a different `ashrafzaryouh` artifact: a 5,845-byte HTML page whose version comparator ran against the Stable Channel constant `[157, 0, 8103, 50]` and labeled patched Extended Stable users on `156.0.8078.96` as vulnerable. That one executed. It produced the wrong answer. This one does not execute.\n\n## Ashraf Zaryouh and the 144-repository pattern\n\nThe committer identity on `ashrafzaryouh/CVE-2026-121529` is `Ashraf Zaryouh `. The same email signs the commits on `ashrafzaryouh/CVE-2026-125350` (yesterday's Chrome HTML) and `ashrafzaryouh/CVE-2026-123488` (a Craft CMS SQLi detection script committed November 9).\n\nThe GitHub account `ashrafzaryouh` was created on 2026-02-06. As of this writing, the account carries 144 public CVE-named repositories, every one of them matching the `CVE-YYYY-NNNNN` pattern. The oldest covered CVE is CVE-2014-6271 (Shellshock) in a 7-kilobyte Python wrapper; the newest is the Fortinet repository above. The spread of covered identifiers includes CVE-2017-0144 (EternalBlue), CVE-2020-5902, CVE-2022-22965 (Spring4Shell), CVE-2024-3094 (xz-utils), and the roster of CVEs that have carried a news cycle in the last twelve years.\n\nThe three most recent, in order:\n\n| Date (UTC) | CVE | What is in the repo | Primitive demonstrated |\n|---|---|---|---|\n| Nov 9 | CVE-2026-123488 | 1 Python file, `detect_cve_2026_123488.py`, 2,828 bytes | None. Baseline vs. `SLEEP(4)` time-delta probe, VULNERABLE path is a `print` statement recommending upgrade. |\n| Nov 10 | CVE-2026-125350 | 1 HTML file, `CVE-2026-125350.html`, 5,845 bytes | None. Browser version-string checker whose hardcoded constant misses Extended Stable. |\n| Nov 11 | CVE-2026-121529 | 1 markdown file, `README.md`, 7,471 bytes | None. Structure block advertises ten uncommitted paths. |\n\nThree days of output. Each repository is faster to produce than the last and contains less executable material than the last. Each one registers identically on a `gh-search` pipeline that counts repositories whose name matches the `CVE-YYYY-NNNNN` pattern. The pipeline's output boolean is `PoC available`.\n\nThe scanner's reasons for CVE-2026-121529 include `gh-search+2`. The scanner's reasons for CVE-2026-125350 the day before included `gh-search+2`. The scanner's reasons for CVE-2026-123488, which this blog has not covered but which triggered the same signal shape, would have included `gh-search+2`. The input to the `gh-search` signal is the repository name. The repository name is the CVE identifier. The CVE identifier is what the author typed.\n\n## The scanner counts names, not code\n\nThe `multi-poc×2+1` bonus on CVE-2026-121529 requires two distinct public sources. The two sources on this candidate are:\n\n1. A Mastodon post with zero engagement, syndicated from a WordPress account owned by the same operator who filed the quoted status, linking an article whose own `Proof-of-Concept Status` section reads `No exploit code has been publicly released`.\n2. A four-kilobyte GitHub repository whose only tracked file is a README, whose `Repository Structure` section advertises ten file paths that have never been committed, and whose caption on the one image it loads from an untracked URL reads `This diagram does not establish a working exploit or verified code-execution chain`.\n\nBoth artifacts state, in their own bodies, that no exploit code exists. The pipeline that summed them to `multi-poc×2+1` did not open either.\n\nThis is the third time in a week this blog has covered the same shape against a `gh-search`-weighted candidate. CVE-2026-11645 (V8) arrived on its June 23 KEV deadline [with three CVE-named repositories that collectively performed zero out-of-bounds operations](/posts/cve-2026-11645-v8-kev-three-pocs-no-oob). CVE-2026-125350 (Chrome XML UAF) arrived yesterday [with two repositories, one a version checker and one a paywall storefront](/posts/cve-2026-125350-chrome-xml-uaf-two-pocs-neither-knows-chrome). Both of those posts covered artifacts that at least executed. This one does not. The decline between the three events is the pipeline's blind spot: the artifact's register value is its name.\n\nThe downstream readers of the `multi-poc` signal are vulnerability-management vendors who sell intelligence feeds priced against counts of PoC-available advisories, federal civilian defenders triaging patch priority against the KEV deadline, and SOC analysts searching GitHub for a PoC to validate their detection posture. All three are served a boolean that was derived from the author's spelling of a CVE identifier.\n\nThe FortiClient bug itself fits a pattern this blog has covered before. FortiClient is deployed to every endpoint in a managed fleet as a defensive agent; its local API exists so the UI can steer the agent's privileges on the endpoint; the CORS flaw lets any webpage ride that trust. That is the [Security Tool As Primitive](/patterns/security-tool-as-primitive) shape in a browser-reachable form: the deploy-everywhere agent whose defensive mission is the capability the attacker inherits. Fortinet's CNA record acknowledges the vector by setting `S:C` (scope changed): the authority being abused is the privilege FortiClient holds on the endpoint, not the browser's.\n\nSomebody has the primitive. Fortinet wrote the patch, so Fortinet has the primitive. The CVE's `E:P` temporal metric says someone else has a proof-of-concept exploit, but the record does not name them and Baldur Security's site does not mention this disclosure. The two artifacts the pipeline registered as evidence of public weaponization are a quote-share and a README. The repository is four kilobytes. The exploit is zero of them.\n\nPoCs: [infosec.exchange/@thecybersecguru/117598221349802056](https://infosec.exchange/@thecybersecguru/117598221349802056), [ashrafzaryouh/CVE-2026-121529](https://github.com/ashrafzaryouh/CVE-2026-121529).","closing_line":"Yesterday's placeholder had code that ran and gave the wrong answer. Today's has no code. The scanner's `multi-poc` signal fired on both.","hook_md":"CVE-2026-121529 is an origin validation error in FortiClient. Fortinet (the CNA) published the record on November 10, 2026 at 20:10 UTC, scored it 9.1 under CVSS 3.1, listed the fixed versions as 7.4.8, 7.2.15, and 8.0.0, and attached the advisory at `https://fortiguard.fortinet.com/psirt/FG-IR-26-194`. The record names no researcher. The CISA ADP block attached to the same record declares `Exploitation: none` and `Automatable: no`. Within twenty hours of publication, two artifacts registered on the vulnerability-intelligence pipeline as public PoCs. One is a Mastodon re-share of a WordPress article whose own body reads `No exploit code has been publicly released.` The other is a four-kilobyte GitHub repository whose only tracked file is `README.md`, and whose `Repository Structure` block advertises ten file paths that have never been committed.","post_id":856,"slug":"cve-2026-121529-fortinet2shell-pocs-are-zero-code","title":"CVE-2026-121529: Fortinet's FortiClient CORS-to-RCE Lands Two \"PoCs\" In Twenty Hours. One Is A Zero-Engagement Boost. The Other Is A README Advertising A Tree That Does Not Exist.","type":"initial","unreadable_sentence":"The two sources the scanner summed to multi-poc are a Mastodon re-share whose linked article declares no exploit exists and a repository whose own README declares no exploit exists. The pipeline reads the names."} -----BEGIN PGP SIGNATURE----- iHUEARYIAB0WIQRf0htP5+SjynlxywneZjl4jgkQJgUCavSBbAAKCRDeZjl4jgkQ JsaRAQDxVtjbUpBwwASgszvD31r/oMoEIfcrFJcxQFtjSQWsuwD/VoCridmueSME 4BqxUlKugCsqtuNiJwmhFs0l7PS0mwM= =mYyF -----END PGP SIGNATURE-----