Agent, CMS, renderer, and export boundary checks from July 9 GHSA updates¶
This update promotes July 9 GHSA records into reusable operator checks for authorized assessments. The shared pattern is trusted automation accepting caller-shaped data after the platform has already made an access, sanitization, locality, or credential-routing decision: MCP tools skip the REST route's scope gate or write outside their workspace, CMS config arrays re-enter framework event binding, CSS imports follow redirects into file://, export jobs turn stored slugs into filesystem paths, and HTTP clients forward bearer material across redirect authorities.
Sources:
- GHSA-382c-vx95-w3p5: Gittensory profile endpoint and MCP tool miss contributor-scoped access control
- GHSA-hm42-q32m-vj4f: Admidio plugin install, uninstall, and update routes accept CSRFable GET requests
- GHSA-3c3g-7hwg-9qmr / CVE-2026-10566: MetaGPT argument mapping reaches deserialization
- GHSA-86vw-x4ww-x467: Craft CMS
FieldsController::actionRenderCardPreviewevent-handler injection - GHSA-c43v-4cr8-6mvp: Craft CMS
assets/icontraversal for local.svgreads - GHSA-9pmc-p236-855h / CVE-2026-53727: Ruby
css_parserSSRF and redirect-to-local-file disclosure - GHSA-rqrh-8wpv-x7hh / CVE-2026-50553: Note Mark export path traversal through unanchored slug validation
- GHSA-588f-fvcv-xhvf / CVE-2026-50554: Note Mark public-book
deleted=truemetadata disclosure - GHSA-q6qc-xp4q-rjq5 / CVE-2026-10281: Claw Orchestrator component API missing authentication
- GHSA-52vm-mxx8-f227: Phantom MCP tools allow arbitrary output paths when
PHANTOM_OUTPUT_DIRis unset - GHSA-q6gh-6v2r-hjv3: Micronaut
DefaultHttpClientforwards sensitive headers across redirect boundaries - GHSA-mr9r-h354-966r / CVE-2026-53639: Sylius shop payment-request endpoints miss ownership checks
- GHSA-6955-hrm5-c4qp / CVE-2026-53638: Sylius shop-account payment-method update misses channel restrictions
- GHSA-5597-7rmh-97q5 / CVE-2026-53637: Sylius cart LiveComponent can mutate completed orders
- GHSA-px5m-h76g-p7p8 / CVE-2026-52778: YesWiki Bazar formula calculator reaches
eval()after regex validation - GHSA-9369-69wj-7m2f / CVE-2026-52777: YesWiki Bazar import entries reach
unserialize() - GHSA-4pf7-cc4r-g63h / CVE-2026-52775: YesWiki ReactionManager route parameters reach SQL concatenation
- GHSA-xc7j-3g8q-9vh4 / CVE-2026-52772: YesWiki Bazar field labels and hints render through
raw('html')
Authorized validation only
Keep proofs in disposable agent, CMS, renderer, HTTP-client, and note-export labs. Use inert MCP calls, synthetic contributor/profile rows, harmless framework event callbacks, owned redirectors, marker-only SVG/export/output files, fake bearer headers, and route/role decision tables. Do not collect financial data, production prompts, secrets, environment dumps, customer notes, real CMS files, real authorization headers, or run shell payloads.
Operator use¶
Use these checks when a scope includes:
- MCP servers or agent platforms that expose the same data through REST and tool transports;
- plugin marketplaces, extension managers, or admin panels where install/update/uninstall routes are reachable through ambient browser sessions;
- agent frameworks that deserialize or reconstruct typed messages from user, repo, checkpoint, or tool-output data;
- Craft CMS or Yii2-based admin features that accept nested config arrays, preview payloads, or
on event-style keys; - server-side CSS parsing for email, rich-text, document preview, or HTML-to-email flows, especially Premailer-style
@importhandling; - note/wiki/export tools that store user-editable slugs and later join them into backup, migration, or archive paths;
- local orchestration dashboards that expose embedded component APIs on browser- or network-reachable ports;
- MCP tools that accept caller-selected input/output paths, especially when a default output root is optional or environment-controlled;
- server-side HTTP clients that follow redirects while carrying
Authorization,Cookie,Proxy-Authorization, or integration API-key headers; - e-commerce APIs where cart, order, payment, payment-request, or account endpoints expose parallel route families with different ownership, channel, or lifecycle checks;
- wiki/CMS form builders where administrator-controlled field definitions, import helpers, reaction APIs, or formula calculators cross into template, SQL, deserialization, or code-evaluation sinks.
Recon checklist¶
| Boundary | What to look for | Safe canary |
|---|---|---|
| REST vs MCP authorization parity | A REST route returns 403 for cross-tenant or cross-contributor access while the sibling MCP tool returns the object | Two disposable users and a synthetic non-sensitive profile field |
| Admin extension state changes | Plugin install, update, uninstall, enable, or import actions accept GET or tokenless requests with ambient cookies | Disposable plugin ID and a reversible no-op install/update marker in a lab |
| Agent message reconstruction | mapping, checkpoint, tool-output, or instruction fields that are converted into typed objects or deserialized classes | Inert class/type marker and local-only harness logs |
| CMS config preview | Nested POST/JSON config passed to framework component constructors without cleansing event-handler keys | Harmless callback such as a marker function in a disposable admin lab, not phpinfo() on production |
| Icon/static helper path construction | User-controlled extension or icon name checked for existence before validation | Temp .svg marker under a lab-controlled readable directory |
| CSS import fetching | @import url(...) accepted from attacker-influenced CSS with base_uri, recursive redirects, or file:// support | Owned HTTP redirector and a temp local canary explicitly placed for the test |
| Export slug-to-path joins | Stored book/note/page slugs validated with unanchored regexes, then used in path.Join, filepath.Join, archive names, or backup paths | Disposable export root and sibling marker directory under /tmp |
| Soft-delete public filters | Public unauthenticated list endpoints that accept deleted, archived, or trash flags and disable ORM scopes | Public test book/note with synthetic title only |
| Embedded component APIs | Component, plugin, or node APIs listening without the same auth as the main dashboard | Route matrix showing unauthenticated 200 vs authenticated control route |
| MCP file output roots | Tool arguments accept absolute paths, .., symlinked output locations, or unset workspace-root environment variables | Temp output root plus a sibling canary path owned by the lab user |
| Redirected HTTP credentials | Client follows 3xx responses to a different host, scheme, or port while preserving sensitive headers | Owned redirector and callback that records only fake canary header names/values |
| E-commerce route-family drift | Checkout endpoints enforce order ownership, channel restrictions, or order state while account/payment-request/cart routes skip the same guard | Two disposable customer accounts, one test order, fake payment method IDs, and marker-only redirect paths |
| Wiki form-builder trust sinks | Form labels, formula fields, CSV/import entries, or reaction IDs flow into template raw output, eval, unserialize, or SQL string construction | Disposable form IDs, harmless field labels, inert serialized fixtures, and SQL syntax canaries in a local lab |
Validation patterns¶
MCP and REST authorization parity¶
The Gittensory advisory is useful beyond that package because it shows a common agent-platform mistake: a route family has object-scoped authorization, but the MCP tool path reconstructs the same object without calling the same guard.
- Enumerate each MCP tool and find the REST/API route or service method it wraps.
- Build a two-user matrix: owner token, non-owner token, REST route decision, MCP tool decision, and returned fields.
- Use synthetic objects with non-sensitive marker fields. A valid proof is the mismatch itself, not the value of private data.
- Stop at field-presence evidence. Redact values and never collect production financial, wallet, prompt, or profile data.
A strong report includes the specific missing guard, the sibling endpoint that enforces it correctly, and a recommendation to share authorization middleware/service checks across transports.
Plugin manager CSRF and ambient admin sessions¶
The Admidio plugin advisory is useful as a general admin-extension boundary check: the browser already holds an admin session, and a tokenless state-changing route lets attacker-controlled HTML steer that session into installing, updating, or removing code-bearing extensions.
- In a disposable application lab, map extension-manager routes and record method, token, and role requirements for install, update, uninstall, enable, import, and configuration actions.
- Build a benign cross-site request harness that targets only a reversible marker action, such as installing a known-safe test plugin, toggling a disposable disabled plugin, or hitting a route that returns a state-change decision without applying it.
- Compare direct admin navigation, same-origin POST with a valid CSRF token, tokenless same-origin GET, and cross-site GET or form-submit behavior.
- Evidence should show the missing anti-CSRF boundary and the resulting extension-control decision. Do not install untrusted packages, remove production plugins, or publish payloads that bootstrap executable plugin code.
Pair this with existing credential-log or private-key-export checks only when the target is Admidio or a similar SSO-capable admin panel. Keep each proof separate: admin browser -> extension state change is a different boundary from session token -> log sink or admin browser -> private-key export.
Agent deserialization and instruction mapping¶
For MetaGPT-style findings, test locally whether message or instruction content can cross from untrusted mapping data into object reconstruction.
- Identify places where agent messages accept
dict, JSON, checkpoint, or tool-returned structures and call constructors, validators, or deserializers. - Keep the harness local and deterministic. Use inert class names or marker methods that prove type selection without executing commands.
- Record the exact call chain: untrusted mapping field ->
check_instruct_contentor equivalent -> deserialization/type reconstruction sink. - Pair any positive result with a fixed-version or hardened parser that rejects unknown type keys or treats the content as plain data.
Do not publish payloads that execute shell commands or read local secrets. The durable operator lesson is the mapping-to-runtime boundary.
Craft CMS preview config and icon helper boundaries¶
Craft's July 9 advisories expose two different admin-side boundaries: config arrays reaching Yii2 event registration, and path validation happening after file-existence checks.
- In a disposable Craft lab, inspect preview/admin endpoints that accept nested
fieldLayoutConfig, element index config, entry-type config, or similar arrays. - Submit a harmless
on init-style marker only if the route is in scope and the lab user has the required admin role. Capture marker execution or a safe error that proves event-handler interpretation. - For icon/static helpers, test extension/path normalization with a lab
.svgmarker file. Evidence should show existence check before validation and a patched negative control. - Avoid environment-dump functions, web shells, or reads of real app files. Use a marker callback and a single synthetic SVG.
CSS parser SSRF and local-file redirect boundary¶
The css_parser advisory is directly reusable for rich-text, email rendering, and document conversion assessments.
- Confirm the application parses attacker-influenced CSS and passes a
base_urior follows@importURLs. - Host an owned
@importURL that first returns a harmless CSS file, then a redirect to an explicitly approved canary destination. - In a lab-only proof, place a temp local file canary and redirect to
file://only when the program owner has approved local-file validation. - Capture outbound request logs, redirect chain, and parsed CSS outcome. Do not target metadata endpoints, loopback admin services, or arbitrary local files.
If the product already has a rich-text import SSRF checklist, fold the evidence into that model: initial URL validation must be repeated after every redirect and scheme transition.
Note export and soft-delete visibility boundaries¶
Note Mark's slug and deleted=true issues are a reminder to test data-lifecycle paths, not just live CRUD routes.
- Create a disposable public book/note pair. Use a slug with traversal syntax plus at least one character that satisfies any suspected unanchored regex.
- Run export/migration into a temp root and confirm whether files are created outside that root. Evidence should be a marker path under
/tmp, not a sensitive system path. - For public list routes, soft-delete a synthetic note and compare unauthenticated responses with and without
deleted=true. - Capture the role state, public/private flag, query parameter, and returned metadata fields. Do not enumerate unknown book IDs or disclose real note content.
Embedded orchestrator component APIs¶
For Claw Orchestrator-style missing-auth component APIs, prefer route-state evidence over destructive calls.
- Map listening ports and route prefixes in a lab deployment.
- Compare the main dashboard/API auth requirement with embedded component endpoints.
- Call only read-only or inert marker endpoints. If a component route is action-capable, prove reachability with an OPTIONS/404/405/route-metadata decision table where possible.
- Report the exposed authority boundary: unauthenticated component API -> component state/action surface -> expected dashboard authentication.
MCP tool path confinement¶
Phantom's advisory is a durable check for any agent-adjacent tool server that lets an LLM, local UI, or remote client supply output paths.
- Enumerate MCP tools that accept path-like parameters:
output,output_path,save_as,workspace,project,audio,render,export, and cache or artifact paths. - Identify the intended confinement root. Treat an unset root environment variable as a finding candidate only in a disposable lab or developer workstation clone.
- Submit marker-only paths that attempt to leave the root: absolute paths under a temp directory,
../sibling-marker, and symlinks pointing to a lab-owned canary path. - Evidence should show pre/post file existence and the effective process user. Do not target shell startup files, editor/plugin startup hooks, credentials, or production project files.
- Pair positive evidence with a patched or configured negative control where the tool resolves symlinks, verifies the final path remains under the root, and creates outputs atomically.
If the same tool decodes compressed media or archives, keep that as a secondary resource-boundary note unless it yields a stronger authorized workflow than availability testing.
Redirect authority and credential forwarding¶
Micronaut's DefaultHttpClient issue is useful for testing integrations that fetch user-provided or third-party URLs while holding service credentials.
- Confirm that the application uses a redirect-following HTTP client for webhooks, imports, link previews, OAuth/OIDC discovery, package metadata, or API relay calls.
- Seed only fake credentials in the lab request context, for example a synthetic Authorization bearer header, a canary Cookie value, Proxy-Authorization, or a lab-only integration header.
- Use an owned first-hop URL that redirects to a different host, scheme, or port you control. Record whether the second-hop request receives any sensitive header.
- Build a decision table by redirect type: same-origin path, same host different scheme, sibling subdomain, unrelated domain, and different port.
- Do not test with live user cookies, production API tokens, OAuth codes, or third-party services. The proof is that header forwarding crosses authority boundaries, not that a real secret was captured.
Sylius payment, order-state, and route-family drift¶
The Sylius advisories are a compact e-commerce authorization lesson: the same business object is reachable through checkout, account, payment-request, and LiveComponent routes, but each route must re-check who owns the object, which channel owns the payment method, and whether the order is still mutable.
- Build a disposable shop lab with two customers, two orders, at least two channels, and fake payment methods that are intentionally enabled for different channels.
- Compare route families for the same object:
- payment-request
GET/PUT/POSTendpoints vs the underlying order owner; - checkout payment update vs shop-account payment update;
- visible cart LiveComponent actions vs the current server-side order state.
- Use marker-only values: fake
target_path/after_pathredirect strings, synthetic payment-method IDs, and test SKUs. Do not process live payments or touch customer orders. - Capture a decision table showing expected negative control and drift: customer A vs customer B, in-channel vs out-of-channel method, mutable cart vs completed order.
- For cart lifecycle races, keep the proof local: open the cart, complete the test order in a second tab or admin lab action, then attempt quantity/remove/clear operations and record whether the completed order changes.
Strong evidence is the missing invariant check, not financial impact: known payment-request hash -> no ownership check -> order token exposure or redirect-field mutation, account payment route -> channel restriction skipped, or stale cart component -> completed order mutated.
YesWiki Bazar and reaction trust boundaries¶
The YesWiki wave is useful for any wiki or CMS that lets privileged users define forms and less-privileged users submit entries. Treat form-builder features as mini programming languages that often bridge into PHP/runtime sinks.
- Enumerate Bazar-style form surfaces: formula/calculated fields, import/CSV actions, reaction routes, field labels, field hints, and Twig/template renderers.
- For formula calculators, prove only parser behavior and safe error/marker outcomes in a disposable lab. Do not publish payloads that execute commands, read files, or stress production regex engines.
- For import helpers, use inert serialized fixtures that demonstrate
unserialize()reachability or class instantiation in a local harness. Avoid gadget chains and secret-bearing objects. - For reaction APIs, prefer syntax and row-scope canaries against a disposable page/form. Evidence should show raw path parameters entering SQL construction; never dump production tables or user data.
- For label/hint rendering, use harmless attribute-breakout markers such as a visible
data-canaryor benign event-free HTML marker. Do not store credential-harvesting or cross-user payloads.
Report these as distinct trust-boundary failures: formula text -> regex sandbox -> eval, POST import entries -> base64 decode -> unserialize, route path parameter -> SQL LIKE construction, and form-builder label/hint -> raw template output. Each proof should include the required role, form ID, route, sink, marker evidence, and a patched negative control when available.
Reporting notes¶
Lead with the boundary that failed:
- authorized REST route -> unaudited MCP wrapper -> cross-object data;
- ambient admin browser -> tokenless plugin-manager route -> extension state change;
- agent message mapping -> deserialization/type reconstruction;
- CMS preview config -> framework event-handler registration;
- icon extension -> pre-validation existence check -> local SVG read;
- CSS
@import-> recursive redirect -> local file or internal fetch; - stored slug -> export path join -> outside-root write;
- public list flag -> soft-delete scope bypass;
- embedded component route -> missing dashboard authentication;
- MCP path parameter -> optional/unset output root -> outside-root write;
- redirect-following HTTP client -> cross-authority 3xx -> sensitive header relay;
- e-commerce alternate route family -> missing ownership/channel/state invariant -> order or payment mutation;
- wiki form-builder/import/reaction input -> runtime sink -> template, SQL, deserialization, or evaluation boundary.
Include version, required role, route/tool name, object ownership, the exact input class, synthetic canary evidence, and a patched or negative control. Avoid generic RCE/SSRF claims unless the approved lab proof reaches that specific sink without relying on sensitive data or production side effects.