npm PraisonAI AgentLoop onToolCall 승인은 도구 실행 후 실행됩니다.
게시된 npm 패키지 praisonai는 createAgentLoop()를 내보냅니다. 이 onToolCall 콜백은 승인 후크로 문서화되고 예시되어 있습니다. 구현에서는 먼저 호출자의 실행 도구를 사용하여 PraisonAI의 generateText() 래퍼를 호출하고 toolResults를 수신한 다음 onToolCall()을 호출합니다.
AI SDK generateText()는 생성 호출의 일부로 execute 기능을 사용하여 도구를 실행하므로 onToolCall은 민감한 부작용이 이미 발생한 후에만 도구를 거부할 수 있습니다. 그런 다음 PraisonAI는 finishReason: "tool_rejected"를 반환합니다. 이는 잘못된 보안 신호입니다. 거부된 도구가 이미 실행되었습니다.
PoV는 결정적이며 로컬 전용입니다. 모의 AI SDK 모듈을 사용하며 라이브 모델 호출, API 키 및 네트워크 대상이 없습니다. 이 도구는 파일 시스템을 건드리거나 명령을 실행하는 대신 메모리 내 카운터를 증가시킵니다.
src/praisonai-ts/src/ai/agent-loop.ts에서 공개 구성은 다음과 같습니다.
``ts /** 도구 호출 콜백 시(승인용) */ onToolCall?: (toolCall: ToolCallInfo) => Promise;
인라인 승인 예제에서는 사용자에게 승인을 요청하고 결정을 반환합니다.
``ts
onToolCall: async (toolCall) => {
const 승인됨 = AskUserForApproval(toolCall)을 기다림;
반품이 승인되었습니다.
}
그러나 AgentLoop.step()은 onToolCall을 호출하기 전에 실행 가능한 도구를 사용하여 generateText()를 호출합니다.
``ts const 결과 = generateText({를 기다립니다. 모델: this.config.model, 메시지: this.messages는 무엇이든 가능합니다. 도구: this.config.tools, 최대 단계: 1, });
그런 다음 `toolResults`를 구체화합니다.
``ts
toolResults: result.toolResults.map(tr => ({
toolCallId: tr.toolCallId,
도구 이름: tr.toolName,
결과: tr.result,
})),
그 후에만 승인 콜백이 실행됩니다.
``ts if (this.config.onToolCall) { for (step.toolCalls의 const toolCall) { const 승인됨 = wait this.config.onToolCall(toolCall); 만약 (!승인) { this.complete = true; step.finishReason = 'tool_rejected'; 부서지다; } } }
`src/praisonai-ts/src/ai/generate-text.ts`는 호출자의 도구를 AI SDK에 직접 전달합니다.
``ts
const 결과 = sdk.generateText({를 기다립니다.
모델,
...
도구: options.tools,
maxSteps: options.maxSteps,
...
});
AI SDK는 'generateText()'가 '텍스트를 생성하고 도구를 호출'하고 'needsApproval'을 사용하여 실행하기 전에 승인을 처리하지 않는 한 'execute' 기능이 있는 도구가 자동으로 실행된다는 점을 문서화합니다.
게시된 npm:praisonai@1.7.1 dist 파일은 동일한 순서를 유지합니다.
dist/ai/agent-loop.js 라인 150-157은 실행 가능한 도구를 사용하여 generateText()를 호출합니다.toolResults를 구체화합니다.onToolCall()을 호출하고 나중에 tool_rejected를 설정합니다.이는 신뢰 모델에만 국한된 문제가 아닙니다. PraisonAI는 'onToolCall'을 승인 콜백으로 명시적으로 라벨링하고 승인 예시를 보여줍니다. 해당 콜백에서 'false'를 반환하는 사용자는 도구가 실행되지 않을 것으로 예상합니다.
또한 PraisonAI가 래핑하는 AI SDK 실행 모델과도 충돌합니다.
needsApproval)입니다.대신 PraisonAI의 현재 동작은 승인으로 이름을 지정하고 문서화하면서 실행 후 감사 후크를 생성합니다.
로컬 복제 체크아웃에서 실행:
``배쉬 노드 poc/pov_poc.js 1.7.1
예상 출력은 다음과 같습니다.
``json
{
"praisonaiVersion": "1.7.1",
"createAgentLoopExported": 사실,
"eventOrder": ["도구 실행", "승인 거부"],
"부작용": 1,
"finishReason": "tool_rejected",
"toolCallCount": 1,
"toolResultCount": 1,
"rejectedAfterExecution": 사실,
"취약한": 사실,
"패치컨트롤": {
"주문": ["승인 거부됨"],
"부작용": 0,
"toolCallCount": 1,
"toolResultCount": 0,
"blocksBeforeExecution": 참
}
}
PoV는 npm:praisonai@1.7.1을 임시 프로젝트에 설치하고 모의 ai 및 @ai-sdk/openai 모듈을 제공합니다. 모의 generateText()는 하나의 도구 호출 인텐트를 반환하고 제공된 execute 핸들러가 있는 경우 이를 실행합니다. 이는 증명의 결정성을 유지하고 PraisonAI의 주문 버그를 격리합니다.
취약한 실행은 다음과 함께 createAgentLoop()를 사용합니다.
execute() 핸들러가 메모리 내 부작용 카운터를 증가시키고 tool-executed를 기록하는 dangerousWrite 도구;관찰된 순서는 다음과 같습니다.
``텍스트 도구 실행 > 승인 거부
이는 실행 후에 거부가 발생한다는 것을 증명합니다. PraisonAI가 `finishReason: "tool_rejected"`를 보고하더라도 `toolResults` 배열에는 도구의 결과가 포함됩니다.
패치 제어 비교는 모델 단계 전에 실행 가능한 핸들러를 제거하고 도구 호출 의도에 대한 승인을 요청하며 승인이 성공한 경우에만 실행됩니다. 동일한 거부 결정으로 제어 출력은 다음과 같습니다.
``텍스트
승인 거부
부작용 = 0
도구결과카운트 = 0
위의 PoV 섹션에는 로컬 재생 명령, 입력 및 결정적인 출력이 포함됩니다.
인간 참여 루프 또는 정책 승인 경계로 'onToolCall'과 함께 npm PraisonAI 'createAgentLoop()'를 사용하는 모든 애플리케이션은 거부된 도구를 실행할 수 있습니다.
애플리케이션이 신뢰도가 낮은 프롬프트나 사용자에게 에이전트 루프를 노출하고 강력한 도구를 등록하는 경우 공격자는 모델이 승인 콜백이 거부하는 도구를 호출하도록 할 수 있습니다. 거부가 너무 늦게 발생합니다. 등록된 도구에 따라 영향에는 파일 수정, 명령 실행, 외부 API 호출, 데이터 변형, 자격 증명 사용 또는 PraisonAI 프로세스 권한과 관련된 기타 부작용이 포함될 수 있습니다.
보고서는 npm PraisonAI가 이를 기본 네트워크 서비스로 노출한다고 주장하지 않습니다. 내보낸 TypeScript 에이전트 루프 API의 라이브러리 수준 승인 경계 우회입니다.
권장 심각도: 높음.
근거:
AV: 일반적인 배포 패턴은 네트워크를 통해 에이전트 프롬프트를 노출하는 애플리케이션입니다.AC: 공격자는 도구 호출만 유도하면 됩니다.UI: 거부 전에 도구를 실행하는 데 추가 운영자 작업이 필요하지 않습니다. 거부 콜백도 너무 늦습니다.S: PraisonAI 호스팅 신청 프로세스에 영향이 있습니다.C/I/A: 등록된 도구에 따라 다릅니다. 쉘/파일/API 도구는 기밀성, 무결성 및 가용성에 영향을 미칠 수 있습니다.관리자가 신뢰할 수 없는 저장소나 프롬프트를 처리하는 로컬 스크립트에만 점수를 매긴다면 'AV:L'이 합리적일 수 있습니다. 이 API를 기반으로 구축된 공개 인증되지 않은 프롬프트 엔드포인트에 점수를 매기는 경우 'PR:N'이 합리적일 수 있습니다.
승인 전에 실행 가능한 도구 핸들러를 generateText()에 전달하지 마세요.
하나의 안전한 모양:
generateText()를 호출하여 모델의 도구 호출 의도를 얻습니다.onToolCall(toolCall)을 호출합니다.또는 PraisonAI가 AI SDK v6에 승인을 위임하려는 경우 'onToolCall'을 도구별 'needsApproval' 의미로 변환하여 AI SDK가 'execute'를 호출하기 전에 일시 중지되도록 합니다.
회귀 테스트에는 다음이 포함되어야 합니다.
onToolCall은 false를 반환하고 도구 execute() 카운터는 0으로 유지됩니다.onToolCall은 true를 반환하고 도구는 정확히 한 번 실행됩니다.MervinPraison/PraisonAInpm:praisonaiAgentLoop1ad58ca02975ff1398efeda694ea2ab78f20cf3ev4.6.581.7.1제안된 영향 범위:
``텍스트 npm:praisonai >= 1.4.0, <= 1.7.1
선택한 버전 스윕:
- `1.0.0`: 선택한 테스트 환경에서는 패키지 메인이 필요할 수 없습니다.
- `1.2.0`: `createAgentLoop`을 내보내지 않습니다.
- `1.3.6`: `createAgentLoop`을 내보내지 않습니다.
- `1.4.0`: 취약함.
- `1.5.0`: 취약함.
- `1.5.4`: 취약함.
- `1.6.0`: 취약함.
- `1.7.0`: 취약함.
- `1.7.1`: 취약함.
## 자문 이력
이는 알려지거나 이전에 제출된 PraisonAI 문제와는 다릅니다.
- 'GHSA-ffp3-3562-8cv3'은 호출 인수가 아닌 도구 이름으로 키가 지정된 Python 'praisonaiagents' 승인 캐시를 다룹니다.
- 'GHSA-qwgj-rrpj-75xm'은 구성된 승인 모드를 'auto'로 재정의하는 Python Chainlit UI를 다룹니다.
- `GHSA-63v4-w882-g4x2` / poc는 Python `HTTPApproval` 승인 페이지 XSS를 다룹니다.
- poc는 npm TypeScript 'AgentOS' 누락된 인증을 다룹니다.
- poc은 npm TypeScript `codeMode` 샌드박스 이스케이프를 다룹니다.
- poc는 npm TypeScript `MCPServer` 누락된 인증을 다룹니다.
도구 결과가 이미 존재한 후에 실행되는 npm TypeScript `AgentLoop.onToolCall`에 대해서는 눈에 띄는 로컬 또는 GitHub 권고가 없습니다.
왜 이 VPI인가 (설명가능 · 실험적)
VPI 산정 기준
| 영향도 | 88.00 |
| 악용 신호(추가 악용신호 없음) | ×1.00 |
| VPI | 88.00 |
VPI 공식 vpi-v1 기준