kiota plugin add / kiota plugin generate (with -t APIPlugin) emits an attacker-controlled static_template.file path from the AI-plugin extensions (x-ai-adaptive-card, x-ai-capabilities) verbatim, with no path validation, into the generated Microsoft 365 Copilot / Teams plugin manifest (<name>-apiplugin.json). An attacker-controlled or compromised OpenAPI description can therefore embed a ../ / absolute path into the manifest's response_semantics.static_template.file, yielding a path traversal (CWE-22) / out-of-package file inclusion (CWE-829) that is resolved by the AI host when the generated plugin is deployed.
Confirmed on Kiota 1.32.4 (KIOTA_CONFIG_PREVIEW=true, the self-contained linux-x64 release binary).
Both extension paths write the static_template.file reference straight into the manifest without sanitization — PluginsGenerationService.GetResponseSemanticsFromAdaptiveCardExtension mints static_template = {"file": <File>}, and the x-ai-capabilities path copies the static_template object through:
# spec -> generated manifest (functions[].capabilities.response_semantics)
x-ai-adaptive-card: {title: T, data_path: $.x,
file: "../../../../../../etc/passwd"} -> static_template.file = "../../../../../../etc/passwd" (CWE-22)
x-ai-capabilities.response_semantics.static_template:
{file: "../../../../../../etc/passwd"} -> static_template.file = "../../../../../../etc/passwd" (CWE-22)
(x-ai-adaptive-card.file only reaches the manifest when title is set, so GetResponseSemanticsFromAdaptiveCardExtension fires; otherwise kiota writes its own template card instead.)
This is not local code execution on the build host. The injected path is written into the generated plugin manifest and realized downstream, when the plugin is packaged and sideloaded / deployed to an AI host...
1.32.51.32.5Exploitability
AV:NAC:LAT:NPR:NUI:NVulnerable System
VC:HVI:HVA:HSubsequent System
SC:NSI:NSA:N9.3/CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N