GHSA-h2w2-v7j6-xqm4: npm PraisonAI AgentLoop onToolCall approval runs after tool execution
Summary
The published npm package praisonai exports createAgentLoop(), whose onToolCall callback is documented and exampled as an approval hook. The implementation calls PraisonAI's generateText() wrapper with the caller's executable tools first, receives toolResults, and only then calls onToolCall().
Because AI SDK generateText() executes tools with an execute function as part of the generation call, onToolCall can deny a tool only after the sensitive side effect has already happened. PraisonAI then returns finishReason: "tool_rejected", which is a false security signal: the rejected tool already ran.
The PoV is deterministic and local-only. It uses mock AI SDK modules, no live model call, no API key, and no network target. The tool increments an in-memory counter rather than touching the filesystem or executing commands.
Technical Details
In src/praisonai-ts/src/ai/agent-loop.ts, the public config says:
/** On tool call callback (for approval) */
onToolCall?: (toolCall: ToolCallInfo) => Promise<boolean>;
The inline approval example also asks a user for approval and returns the decision:
onToolCall: async (toolCall) => {
const approved = await askUserForApproval(toolCall);
return approved;
}
However, AgentLoop.step() calls generateText() with the executable tools before invoking onToolCall:
const result = await generateText({
model: this.config.model,
messages: this.messages as any,
tools: this.config.tools,
maxSteps: 1,
});
It then materializes toolResults:
toolResults: result.toolResults.map(tr => ({
toolCallId: tr.toolCallId,
toolName: tr.toolName,
result: tr.result,
})),
Only afterward does the approval callback run:
if (this.config.onToolCall) {
for (const toolCall of step.toolCalls) {
const approved = await this.config.onToolCall(toolCall);
if (!approved) {
this.complete = true;
step.finishReason = 'tool_rejected';
break;
}
}
}
src/praisonai-ts/src/ai/generate-text.ts forwards the caller's tools directly to AI SDK:
const result = await sdk.gen
Details
Original advisory: https://github.com/advisories/GHSA-h2w2-v7j6-xqm4
Referenced CVEs
| CVE | CSIRTS overview | External |
|---|---|---|
| CVE-2026-57137 | coverage & exploitation status | NVD · CVE.org |
More from GitHub Security Advisories
- mediumGHSA-xm43-3m56-w3wf: Ghost: Paid gift memberships obtainable at minimal cost via the donations feature2026-08-04
- mediumGHSA-chgm-3698-jm42: Ghost: Member existence leak via magic link sign-in response2026-08-04
- highGHSA-xpp7-93x6-v29m: XSS in Ghost's ActivityPub client2026-08-04
- mediumGHSA-7mpp-r37j-x5wh: Ghost: Session Fixation in Ghost Admin2026-08-04
- mediumGHSA-cjc9-q5gf-327p: Ghost: Theme Upload Path Traversal2026-08-04