PraisonAI agent/platform control boundaries and Formie submission overwrite batch¶
Source: GitHub Security Advisories REST fallback, updated 2026-05-29: GHSA-vg22-4gmj-prxw / CVE-2026-47391, GHSA-4mr5-g6f9-cfrh / CVE-2026-47392, GHSA-8444-4fhq-fxpq / CVE-2026-47393, GHSA-9cr9-25q5-8prj / CVE-2026-47394, GHSA-5cxw-77wg-jrf3 / CVE-2026-47395, GHSA-86qc-r5v2-v6x6 / CVE-2026-47396, GHSA-hvhp-v2gc-268q / CVE-2026-47397, GHSA-78r8-wwqv-r299 / CVE-2026-47398, GHSA-5c6w-wwfq-7qqm / CVE-2026-47390, GHSA-3qg8-5g3r-79v5 / CVE-2026-47410, GHSA-h8q5-cp56-rr65 / CVE-2026-47407, GHSA-6h6v-6m7w-7vxx / CVE-2026-47399, GHSA-gv23-xrm3-8c62 / CVE-2026-48169, GHSA-h37g-4h4p-9x97 / CVE-2026-47405, GHSA-w388-2392-px73 / CVE-2026-47409, GHSA-c2m8-4gcg-v22g / CVE-2026-47416, GHSA-4x6r-9v57-3gqw / CVE-2026-47406, GHSA-5jx9-w35f-vp65 / CVE-2026-47414, and GHSA-pgxq-p76c-x9cg / CVE-2026-47266.
This batch is durable because it captures reusable offensive validation patterns for agent stacks: public unauthenticated agent control planes, LLM-driven tool invocation into unsafe sinks, prompt/mention SSRF, MCP file-read boundaries, sandbox escape regression checks, untrusted project/module execution, workspace-scope IDOR, role escalation, hardcoded development secrets, and unauthenticated form-submission overwrite.
What changed¶
- PraisonAI A2A example tool execution — the first-party unauthenticated A2A example binds to
0.0.0.0, accepts/a2amessage/send, and registers an unsafecalculatetool implemented with Pythoneval(). - PraisonAI Python sandbox escape —
execute_code()subprocess mode missedprint.__self__andvars()paths that can recover the real builtins module despite earlier sandbox patches. - PraisonAI generated API server auth-disabled default —
praisonai deploy --type apican emit a Flask/chatand/agentsserver whereauth_enableddefaults to false while user workflows may bind externally. - PraisonAI call server fail-open auth —
CALL_SERVER_TOKENunset makes the agent invocation router return successfully from its auth dependency, exposing agent listing, metadata, invocation, and deletion. - PraisonAI MCP file-read residuals — the prior rules-path fix missed
workflow.show,workflow.validate, anddeploy.validate, leaving unauthenticated MCPtools/callpaths that read arbitrary host files or leak fragments through parser errors. - PraisonAI SSRF and file-write agent boundaries —
@url:prompt mentions and spider tools can fetch loopback/private-like URLs through weak normalization, while web-crawled hidden metadata can steerwrite_filewhen production passesworkspace=None. - PraisonAI untrusted module execution — YAML-controlled
module_pathvalues inagents_generator.pystill reach unguardedspec.loader.exec_module()sinks, bypassing earlier local-tool gates. - PraisonAI Platform tenant isolation failures — workspace routes check membership on the URL workspace but fetch inner resources by global ID; member-management routes only require ordinary membership; several advisories also cover hardcoded
dev-secret-change-meJWT defaults, role-promotion, member removal, dependency/label IDOR, and activity-log disclosure. - Formie front-end submission overwrite — unauthenticated users can post a known or guessed submission ID to the front-end save action and overwrite existing Craft CMS Formie submissions.
Operator triage¶
- Separate example risk from deployed pattern risk: the A2A
eval()issue is strongest where teams copied the official unauthenticated example or exposed an A2A service with comparable unsafe local tools. - Map every agent-facing network listener: check A2A, generated Flask API, call server, MCP server, and platform API separately; each has a distinct auth/default boundary.
- Treat prompt preprocessing as fetch-capable input:
@url:and crawler-derived content are pre-tool trust boundaries, not harmless context decoration. - Bind workspace ID to object ID: PraisonAI Platform findings are a clean test case for cross-tenant object substitution in routes that appear workspace-scoped.
- Use canaries, not secrets: validate file reads/writes, SSRF, and code execution with synthetic files, callback endpoints, marker values, and disposable workspaces only.
- For Formie, require owner-approved test records: submission overwrite validation should use a known lab submission ID, never guessed production records.
Replayable validation boundaries¶
PraisonAI exposed agent service checks¶
- Inventory reachable PraisonAI listeners and record component, bind address, version, and authentication state.
- For A2A, use a lab server copied from the affected example and a harmless calculation/canary tool. Prove that unauthenticated
message/sendcan reach tool invocation without running OS-impacting commands. - For generated Flask API, run
deploy --type apiin a disposable project and confirm whether/chatand/agentsaccept requests without an auth header under default config. - For the call server, start a lab instance with
CALL_SERVER_TOKENunset and verify unauthenticated agent listing/invocation against a benign echo agent; repeat with a token set to show the missing-token default is the boundary.
PraisonAI MCP and local filesystem checks¶
- Use a disposable MCP server process under a test Unix user.
- Create a canary file outside the expected workflow directory, then call
workflow.show,workflow.validate, ordeploy.validatewith that path. - Capture whether the response returns full content, file-existence evidence, or parser-error fragments.
- Avoid targeting real keys,
.envfiles, cloud credentials, or system secrets; the report should show the path-containment gap without collecting sensitive data.
PraisonAI prompt fetch, crawler, and write-file checks¶
- For
@url:, run the CLI with a tester-controlled loopback HTTP service that returns a synthetic marker and confirm it is prepended to model context. - Repeat with alternate loopback spellings only in a lab to show URL-normalization drift.
- For crawler-to-write-file, host a page containing benign hidden metadata that requests a temp-directory canary write. Verify that production
workspace=Noneskips containment and writes only the marker file. - Record the exact prompt/crawler path that introduced the attacker-controlled metadata; this distinguishes model behavior from tool-boundary failure.
PraisonAI sandbox and module-loading checks¶
- For
execute_code(), validate in an isolated container with no secrets mounted. Use a marker-only proof such as reading an environment variable set solely for the test or writing a temp canary. - Confirm the bypass survives the target version's existing blocked-attribute patches before claiming regression impact.
- For
agents_generator.py, supply a YAMLmodule_pathto a benign local module that only emits a marker, then show it executes withoutPRAISONAI_ALLOW_LOCAL_TOOLSor equivalent approval.
PraisonAI Platform workspace isolation checks¶
- Create two disposable workspaces and two low-privileged users.
- In workspace A, make the caller a normal member. In workspace B, create synthetic agents, projects, issues, labels, comments, and dependencies.
- Send requests under
/api/v1/workspaces/{workspace_A}/...while substituting object IDs from workspace B; stop at read-only proof where possible, or mutate only synthetic records. - Test member-management actions from a normal member account: self-promotion, adding an owner/admin, role changes, and member removal. Restore all lab memberships afterward.
- If
PLATFORM_ENVis unset, verify whether JWTs signed with the documented development secret are accepted against a lab account; do not forge real-user tokens.
Formie submission overwrite check¶
- In a lab Craft CMS/Formie instance or explicitly authorized staging form, create a harmless submission and record its ID.
- Submit to
actions/formie/submissions/save-submissionor the equivalent front-end action without authentication, using only the lab submission ID. - Prove that fields are overwritten or rejected based on the patched/unpatched version. Avoid guessing or enumerating production IDs.
Reporting heuristics¶
- For PraisonAI, report by boundary rather than dumping all CVEs together: exposed service auth, prompt/URL fetch, MCP file access, sandbox escape, untrusted module loading, and platform tenant isolation.
- Include the exact role used, environment variables set or unset, bind address, route, and whether the test came from a documented quickstart/example.
- For tenant IDOR, always include both IDs: the workspace authorized by the route prefix and the object whose owning workspace differed.
- For sandbox/module execution, keep evidence to marker-only execution and name the missing validation primitive (
__self__,vars, unguardedexec_module, or missing local-tool gate). - For Formie, include whether front-end editing is enabled, the affected Formie major version, and the unauthorized submission ID overwrite path.
Notes on skipped items from this scan¶
- Bazaar
bzr+sshdash-prefixed hostname command execution was updated in GitHub Advisories but is an old 2017 issue; it remains useful supply-chain history, not fresh Skillz Wiki content. - PraisonAI activity-log disclosure and several narrower dependency/label/member-management advisories were folded into the broader platform tenant-isolation/role-escalation workflow instead of each receiving a standalone page.
- Stigmem items updated around the same window were configuration-obvious, defensive-hardening, or already reviewed in the prior scan.
- CISA KEV stayed catalog
2026.05.29with PAN-OS CVE-2026-0257 already reflected. PortSwigger, ProjectDiscovery, GitHub Security Blog, Trail of Bits/feed.xml, and Disclosed had no separate promotable deltas in this pass.