Skip to content

YesWiki 4.6.7 wave — secondary-handler ACL drift, federation signature binding, deferred identifier SQLi, and GET-mutation CSRF

Source: GitHub Security Advisory wave published 2026-10-02 12:31Z (YesWiki < 4.6.7, 36 GHSAs; CVE-2026-104438–104472). Related existing pages: Sept 18 semantic-MediaWiki unauth API page, Sept 21 management-plane flat-authz drift page, Sept 19 WordPress alternate-surface page.

One rule covers the majority of this wave: the ACL is written where the page renders, not where the page data is read or written. YesWiki ships dozens of sibling handlers over the same storage — attachment download, RSS actions, the comments API, the triples API, Bazar entry creation, tag listings, image actions — and most of them never call the read/write ACL check. On any wiki/CMS with per-page ACLs, build the handler inventory first; the primary render path passing its ACL tests tells you nothing.

What changed (promoted legs)

Advisory Handler Boundary Operator value
GHSA-m45w-rvq4-f22g / CVE-2026-104472 (7.5) Attachment download handler Unauthenticated: known page tag + file param returns attachments from read-ACL-restricted pages Attachments are a second read path with no ACL call. Enumerate ?download/ style handlers with guessed tag+filename pairs against restricted pages
GHSA-h2q6-cgj7-p65g / CVE-2026-104449 (6.5) Bazar entry creation Unauthenticated write: crafted entry with id_fiche matching an existing page overwrites its body, write-ACL bypassed Creation flows that accept a caller-chosen target identifier are write primitives on existing rows. Try to "create" over something you don't own
GHSA-mf95-w988-564j / CVE-2026-104450 (6.5) pointimage action (tools/attach) Unauthenticated POST saves content to an attacker-chosen page with write-ACL checks bypassed Third write path around the same pages table — count the routes that can save, not the bugs
GHSA-gr78-chgv-6fgg / CVE-2026-104443 (8.1) Triples delete API Empty-filter scope bypass: any authenticated user deletes/forges arbitrary semantic triples regardless of ownership — deleting the admins-group membership triple empties the admin group Delete/maintenance endpoints where an empty filter means "everything" instead of "nothing". Also a deliberate lockout tool — prove with your own disposable group only
GHSA-gch9-x4v5-hp56 / CVE-2026-104444 (7.1) Comments API editComment Low-privilege authenticated users overwrite arbitrary pages/comments by supplying their own page as the pagetag field while targeting a victim tag — per-page write ACL bypassed, content replaced and pages reparented Authorization checked on the wrong object of a two-object request (your own pagetag passes the check while the victim tag is the actual write target). Whenever a request carries two identifiers, confirm which one the permission check resolves — the Sept 21 Blazar "authorizes-under-wrong-param" twin
GHSA-59xh-vh54-x5hf / CVE-2026-104467 (8.1 critical) ApiService::isAuthorized() Unauthenticated calls to admin-only API routes (api/ci/update_config, api/archives list/download/delete) when public API mode is enabled A product feature flag (public API) silently widens the route ceiling to admin scope. Toggle-state-dependent route families must be re-authorized-matrixed in each state. Config overwrite + backup archive read/delete from one unauthenticated call
GHSA-x8xj-595c-jcc3 / CVE-2026-104455 (5.3) recentchangesrssplus action Unauthenticated xml method returns 500-char excerpts of every latest page including read-restricted drafts/notes RSS/feed actions are read paths that skip read-ACL filtering. Request every action's alternate output method (xml, rss, json) on pages whose HTML view correctly denies you
GHSA-fm39-cmv6-r4rj / CVE-2026-104438 listpagestag / includepages (tags tool) Page listings with no read-ACL filtering, unauthenticated Listing actions leak restricted page titles/sets — the tag graph is a disclosure map for what exists behind ACLs
GHSA-px48-25j6-h73c / CVE-2026-104445 (8.2) ActivityPub inbox HTTP signature verified but signer never bound to the activity actor — any valid keypair can send signed Delete/Update referencing a mirrored entry's sourceUrl to delete/overwrite other actors' federated content Federation signature-binding axis: signature verified ✓ ≠ signer == actor. On any ActivityPub/inbox handler: sign an activity with your own key, point actor/sourceUrl at a victim entry, and see what accepts it. Same invariant applies to webhook signing (compare: n8n trigger-HMAC class on the Oct 1 page)
GHSA-ghw3-mg2w-7jg2 / CVE-2026-104464 (8.6) Bazar abonnements sync action Unauthenticated SSRF via unvalidated actor URL, and the fetched response is stored as a readable Bazar entry — full read-back; attacker-controlled outbox first/next links chain further server-side fetches Two durable SSRF upgrades in one bug: (1) read-back by design (fetched content persisted as user-visible content, not blind), (2) link-chained multi-hop crawl — your callback returns a JSON-LD outbox whose next points at 169.254.169.254 and the crawler walks there itself. Test federation/sync fetchers for response persistence and pagination-following, not just first-hop reachability
GHSA-jf5x-83r6-59f3 / CVE-2026-104442 (5.8) render.php content param → syndication action Unauthenticated SSRF, fetched feed content rendered back into the page, and feed enclosures downloaded into the web-accessible files directory SSRF → arbitrary-file-write-into-webroot via enclosure handling. When a fetcher "helpfully" localizes remote assets, the download leg inherits the SSRF destination
GHSA-pg4j-r96p-6rg4 / CVE-2026-104459 (6.5) WebfingerService Unauthenticated HTTPS requests via actor_handle with a numeric host and port (dotted-decimal/integer IP form) Alternate address encodings defeat string denylists (http://2130706433/ style). Include decimal/octal/hex host spellings in every SSRF battery
GHSA-992m-5rj6-qxj2 / CVE-2026-104440 (5.3) /api/entries/bazarlist idtypeannonce Blind SSRF because isValidURL() always returns true When you can read source (or error-text gives it away), grep the validator — a function that unconditionally returns true is a documented bypass. Black-box equivalent: the parameter accepts everything you expected to be blocked
GHSA-m352-5gh7-99x6 / CVE-2026-104456 (7.6) AclService::updateRequestWithACL Second-order SQLi: self-register a username containing a double-quote payload; later ACL-filtered listings concatenate the stored username unescaped into a LIKE clause → read DB contents, bypass read ACLs Identifier-as-injection-vector, self-seeded: register/store the payload in an identity field nobody escapes, then trigger the consumer query (listings, exports, searches). The write is trivially legal; the read is deferred
GHSA-3q4q-74cq-96xq / CVE-2026-104460 (7.5) {{newtextsearch}} action Blind SQLi: Bazar list option ids concatenated into REGEXP/LIKE clauses; anonymous attackers plant the malicious option id in an anonymously editable Bazar list, then use search requests as a boolean oracle to read arbitrary tables incl. password hashes Deferred SQLi with a planted value: the injection point reads config someone else can edit anonymously. Map every "option/config" store that search/list code later interpolates
GHSA-f8w7-2q27-5p28 / CVE-2026-104457 (8.6) Bazar filtertags action SQLi via trailing-backslash token that breaks quote parity under MySQL backslash escaping → five-column UNION subquery reading arbitrary data The escape-the-escape class: input \"-style handling differs between the app's quote-wrapping and MySQL's string parser — a trailing \ swallows the closing quote. Always test trailing backslashes on every quote-wrapped SQL parameter, and match UNION column arity from error/behavior probing
GHSA-mvpf-2445-p988 / CVE-2026-104462 (7.5) Bazar nuagetag action Unescaped tags attribute into raw IN (...) clause; page-write access = unauthenticated on default installs Default-install privilege floor: "authenticated editor" primitives are unauthenticated out of the box on this CMS. Baseline what a fresh install lets an anonymous visitor do before testing authenticated paths
GHSA-6qxf-8854-q5c5 / CVE-2026-104448 (8.1) ajaxdeletepage Permanent page delete on GET carrying jsonp_callback, no CSRF token Destructive-GET sweep: GET every admin/UI handler with a mutating-looking name; a JSONP-era callback param that re-enables the handler is the giveaway. Revision-restore (CVE-2026-104451), filemanager attachment delete (CVE-2026-104452), admintag delete (CVE-2026-104453), autoupdate package delete (CVE-2026-104447) are the same class across five handlers — a whole product's worth of unprotected GET mutations
GHSA-g4m2-8g7g-xw8c / CVE-2026-104471 (7.2) Bazar CSV import preview Authenticated admin: CSV whose file/image field is a remote URL → server writes the fetched remote file into web-accessible files/ "Preview" fetches the remote value before import finalizes — an import-preview leg is an SSRF+write even when the upload path itself is restricted. Test preview with remote URLs, not just local files
GHSA-c9hw-c2mv-jj5c / CVE-2026-104469 (6.8) Login Session fixation: no session-id regeneration on login; plant a pre-auth YesWiki-* cookie, victim logs in, you ride the known id Standard fixation re-check on every CMS: plant → authenticate victim in lab → does the session id survive login?
GHSA-6c43-xgw2-65px / CVE-2026-104468 (4.8) Password reset Reset tokens lack expiry timestamps — unused links work forever from old mailboxes/logs/backups Password-reset tokens: check expiry and single-use. An old leaked reset URL that still works is a persistent ATO foothold; sweep historic mail archives in phishing-scope engagements
GHSA-c595-8pv9-m3vm / CVE-2026-104446 (6.5) Contact mail AJAX handler Unauthenticated email relay through the wiki's SMTP (fields absent from the AJAX shape skip validation) AJAX variants of form handlers validate a different field set than the form path — unauthenticated send-mail relay. POST the AJAX shape, not just the form
GHSA-c49r-h57h-8wfx / CVE-2026-104461 (5.4) Bazar FileField Upload validated by extension only; the HTML-purifier file-clean step is never called → SVG stored verbatim and served inline → stored XSS Extension-check-only + skipped sanitizer = the two-defect pair that makes SVG upload work. Try SVG-with-script on every "document" upload field, then confirm the serving context renders it inline

Durable axes

  1. Per-page ACL is a property of the render path only — enumerate sibling handlers over the same storage. This single CMS shipped unauthenticated reads (attachment download, RSS excerpts, tag listings, triples reads) and unauthenticated/low-priv writes (entry-creation-by-existing-id, pointimage save, comments-API page targeting) all around the same page ACL. On any wiki/CMS/knowledge-base target: list every action/API/output-format that touches page content, then replay both ACL axes (read restricted, write not-yours) through each handler. The primary view correctly denying you is the control, not the result.
  2. Feature flags change the route ceiling. Public-API mode turned admin routes (update_config, archive list/download/delete) into unauthenticated surface. Rebuild the authorization matrix per feature-flag state; toggle flags you can influence via config write or trial installs and re-probe the API family.
  3. Empty/default filters on bulk APIs are apply-all by default. An empty filter on a delete endpoint = site-wide destruction. Always send {} / omit the filter object; expect a validation error, and report when you get a mutation. Pair with the delete-then-repopulate reality (deleting your own lab group's membership triple as proof).
  4. Federation/webhook invariants: signature-verified must bind signer to actor. Verify the identity inside the payload is the identity that holds the key. Test cross-actor Delete/Update with your own valid keypair on ActivityPub inboxes; test cross-tenant replay on every HMAC'd webhook receiver.
  5. Deferred identifier SQLi: the injection write and read are different requests by different code. Your username, a planted Bazar option id, a stored tag token — anything persisted unescaped and later interpolated into a query. Sweep: store quote/backslash variants in every identity/config field you can set (including anonymously editable config), then trigger every listing, search, feed, and export consumer.
  6. MySQL backslash quote-parity breakout. A trailing \ in a value the app merely wraps in quotes swallows the closing quote under MySQL's default escaping and reopens the string. Include \" , \ and double-encoded spellings in every quote-wrapped parameter battery; recover column arity for UNION via error/boolean probing.
  7. Destructive GET is a product-wide pattern, not a single bug. Five separate handlers in one product deleted pages, attachments, tags, packages, and revisions on unauthenticated-for-CSRF GET. A GET sweep of mutating handlers with disposable state enumerates the whole class in an afternoon.
  8. Fetchers inherit their destination: sync/preview/syndication legs read back (content persisted as viewable entries), crawl on (attacker-controlled next links), and localize (enclosures downloaded into webroot). Each leg upgrades blind SSRF into read, multi-hop, or file-write — test all three per fetcher.

Validation boundaries

Lab YesWiki < 4.6.7 with disposable pages, two synthetic accounts, marker attachments, and synthetic Bazar lists only. SSRF proofs use owned callbacks and self-owned multi-hop JSON-LD responders; never target cloud metadata or third-party internal hosts. SQLi proofs read marker rows and stop — no real user-table dumps in reports (hash extraction described, not performed, on shared instances). ActivityPub proofs use your own keypairs and mirrored synthetic entries; never delete or overwrite real federated content. GET-mutation proofs fire only against your own disposable pages/packages. Fixation/reset proofs use lab victim sessions you control.

October 4 18:3xZ follow-up: the valeur.php fetch-and-render pair — one handler, SSRF leg + stored-XSS leg

Two advisories for the same Bazar valeur action (tools/bazar/actions/valeur.php) landed split across waves — the SSRF leg published Oct 2 (surfaced in the updated feed Oct 4), the XSS leg Oct 4:

  • GHSA-32r4-8mw9-77h4 / CVE-2026-104470 (medium) — page-editor url parameter makes the server fetch arbitrary URLs (loopback/internal probing) and injects the fetched remote HTML unescaped into the rendered page.
  • GHSA-4jc3-v5mf-cppg / CVE-2026-105224 (medium) — same handler pointed at a controlled server returning BAZ_fiche_titre markup with an img onerror executes script in every viewer's browser — editor-privilege foothold becomes stored XSS against all readers.

Durable axes: (1) a fetch-and-render action is two bugs wearing one coat — probe it once for internal-URL acceptance (SSRF) and once for remote-HTML execution (viewer-side XSS); the impact split (editor-only authority vs all-viewer execution) makes the XSS leg the escalation path. (2) This extends durable axis 8 (fetchers inherit their destination) with a fourth leg: render — the fetched bytes are emitted into the page DOM, not just stored or followed. When you find any "embed/fetch/preview a URL" field, the full battery is read-back / crawl-on / localize / render. (3) Same-handler advisories split across days: when you fold one leg of a product's fetch handler, grep the advisory feed for the sibling CVE/param before closing the page.

Tracked from this wave without publication

  • YesWiki XSS/DoS singles: wakka.php markdown-image-quote stored XSS (CVE-2026-104466), reflected XSS via field/incomingurl/id/file/tags/template params (CVE-2026-104465/104473), O(n²) bracket-body formatter DoS (CVE-2026-104454), user enumeration via differing LostPassword responses (CVE-2026-104439) — generic classes already canonical on existing pages.
  • Same-wave Apache Thrift < 0.25.0 seventeen-GHSA language-binding pack (CVE-2026-82458/86535/86536/86537/90440/91137/94633/94636/94645/94646/94651/96288/96292/97876/85086/93926 + NodeJS TJSONProtocol prototype pollution) — parser memory-safety/DoS in non-primary bindings, tracked per parser precedent; recon note kept: exposed Thrift binary-protocol RPC ports (no HTTP) fingerprint via zero-length/oversized-field probes, and Node/Dart/Python binding fixes are per-language — fingerprint the binding, not just "Thrift".
  • Zcash Zebra node eighteen-GHSA pack (consensus divergence, peer-discarded provenance, mempool-limit bypass, block-sync DoS) — consensus/memory-safety class, no reusable operator workflow at advisory detail level; revisit if a consensus-divergence advisory ships with protocol-level exploit detail.
  • SiYuan publish-reader trio promoted as a fold (see July 10 File Browser/SiYuan page); Ghost eight-pack folded on the Aug 4 Ghost page.
  • HospitalManagementSystem ID-parameter SQLi (thin detail), GRUB Secure Boot lockdown bypass (local/boot class), unnamed protocol-gateway account_name stack overflow (detail-free), itsourcecode singles — processed class.