GHSA-P5RM-JG5C-8C77
Vulnerability from github – Published: 2026-07-24 16:14 – Updated: 2026-07-24 16:14Impact
Kiota generates AI plugin manifests from an OpenAPI description. When the description contains an x-ai-capabilities response semantics static_template (or the adaptive-card extension x-ai-adaptive-card), the file reference is written into the generated manifest's response_semantics.static_template.file and is later resolved by the AI host relative to the plugin package.
An attacker who controls or tampers with the OpenAPI description consumed by Kiota can supply a file reference that resolves outside the manifest package (e.g. ../../../../etc/passwd, an absolute path, or a file:// / http(s):// URI). When the generated manifest is deployed and consumed by an AI host, this can lead to inclusion or disclosure of files outside the intended package boundary (CWE-22 Path Traversal, CWE-829 Inclusion of Functionality from an Untrusted Control Sphere).
A mitigation shipped in v1.32.5 (ExtensionResponseSemanticsStaticTemplate.IsSafeFileReference) rejected literal traversal, rooted paths, drive-qualified paths, and absolute URIs. However, that check inspected the raw reference string, so percent-encoded payloads bypassed every check and were still emitted verbatim. Examples that were incorrectly accepted as safe:
| Input | Decodes to |
|---|---|
%2e%2e/card.json |
../card.json |
..%2f..%2f..%2f..%2f..%2f..%2fetc%2fpasswd |
../../../../../../etc/passwd |
file%3A%2F%2F%2Fetc%2Fpasswd |
file:///etc/passwd |
%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd |
../../../etc/passwd |
Multi-level (double) encoding such as %252e%252e%252fcard.json was also affected. A follow-up review found additional residual bypasses of the same validator: an embedded NUL byte (%00) that truncated the path and defeated the parent-directory segment check, encoding nested deeper than the decode budget (which failed open), and Unicode full-width homoglyphs (e.g. %EF%BC%8E%EF%BC%8E → ..).
Patches
- The percent-encoding bypass is fixed by decoding the reference (bounded multi-pass) before validation: https://github.com/microsoft/kiota/pull/7910
- Residual bypasses (NUL / control characters, decode-budget fail-open, Unicode homoglyphs) are fixed by failing closed on residual encoding, rejecting control characters, and NFKC-folding before validation: https://github.com/microsoft/kiota/pull/7913 (tracking issue https://github.com/microsoft/kiota/issues/7912)
Users should upgrade to the first released Microsoft.OpenApi.Kiota version that includes these fixes (the release following 1.33.0).
Workarounds
- Only generate clients/plugins from trusted OpenAPI descriptions.
- Review generated plugin manifests before deployment and reject any
response_semantics.static_template.filevalue that is not a simple relative path within theadaptiveCards/package folder (no.., no rooted/absolute paths, no URIs, no percent-encoded separators).
References
- CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
- CWE-829: Inclusion of Functionality from an Untrusted Control Sphere
- Affected code:
src/Kiota.Builder/OpenApiExtensions/OpenApiAiCapabilitiesExtension.cs(IsSafeFileReference) and enforcement insrc/Kiota.Builder/Plugins/PluginsGenerationService.cs.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 1.33.0"
},
"package": {
"ecosystem": "NuGet",
"name": "Microsoft.OpenApi.Kiota"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.34.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-22",
"CWE-829"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-24T16:14:56Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "### Impact\n\nKiota generates AI plugin manifests from an OpenAPI description. When the description contains an `x-ai-capabilities` response semantics `static_template` (or the adaptive-card extension `x-ai-adaptive-card`), the `file` reference is written into the generated manifest\u0027s `response_semantics.static_template.file` and is later resolved by the AI host **relative to the plugin package**.\n\nAn attacker who controls or tampers with the OpenAPI description consumed by Kiota can supply a `file` reference that resolves **outside** the manifest package (e.g. `../../../../etc/passwd`, an absolute path, or a `file://` / `http(s)://` URI). When the generated manifest is deployed and consumed by an AI host, this can lead to inclusion or disclosure of files outside the intended package boundary (CWE-22 Path Traversal, CWE-829 Inclusion of Functionality from an Untrusted Control Sphere).\n\nA mitigation shipped in v1.32.5 (`ExtensionResponseSemanticsStaticTemplate.IsSafeFileReference`) rejected literal traversal, rooted paths, drive-qualified paths, and absolute URIs. However, that check inspected the **raw** reference string, so **percent-encoded** payloads bypassed every check and were still emitted verbatim. Examples that were incorrectly accepted as safe:\n\n| Input | Decodes to |\n|-------|-----------|\n| `%2e%2e/card.json` | `../card.json` |\n| `..%2f..%2f..%2f..%2f..%2f..%2fetc%2fpasswd` | `../../../../../../etc/passwd` |\n| `file%3A%2F%2F%2Fetc%2Fpasswd` | `file:///etc/passwd` |\n| `%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd` | `../../../etc/passwd` |\n\nMulti-level (double) encoding such as `%252e%252e%252fcard.json` was also affected. A follow-up review found additional residual bypasses of the same validator: an embedded NUL byte (`%00`) that truncated the path and defeated the parent-directory segment check, encoding nested deeper than the decode budget (which failed open), and Unicode full-width homoglyphs (e.g. `%EF%BC%8E%EF%BC%8E` \u2192 `\uff0e\uff0e`).\n\n### Patches\n\n- The percent-encoding bypass is fixed by decoding the reference (bounded multi-pass) before validation: https://github.com/microsoft/kiota/pull/7910\n- Residual bypasses (NUL / control characters, decode-budget fail-open, Unicode homoglyphs) are fixed by failing closed on residual encoding, rejecting control characters, and NFKC-folding before validation: https://github.com/microsoft/kiota/pull/7913 (tracking issue https://github.com/microsoft/kiota/issues/7912)\n\nUsers should upgrade to the first released `Microsoft.OpenApi.Kiota` version that includes these fixes (the release following 1.33.0).\n\n### Workarounds\n\n- Only generate clients/plugins from trusted OpenAPI descriptions.\n- Review generated plugin manifests before deployment and reject any `response_semantics.static_template.file` value that is not a simple relative path within the `adaptiveCards/` package folder (no `..`, no rooted/absolute paths, no URIs, no percent-encoded separators).\n\n### References\n\n- CWE-22: Improper Limitation of a Pathname to a Restricted Directory (\u0027Path Traversal\u0027)\n- CWE-829: Inclusion of Functionality from an Untrusted Control Sphere\n- Affected code: `src/Kiota.Builder/OpenApiExtensions/OpenApiAiCapabilitiesExtension.cs` (`IsSafeFileReference`) and enforcement in `src/Kiota.Builder/Plugins/PluginsGenerationService.cs`.",
"id": "GHSA-p5rm-jg5c-8c77",
"modified": "2026-07-24T16:14:56Z",
"published": "2026-07-24T16:14:56Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/microsoft/kiota/security/advisories/GHSA-p5rm-jg5c-8c77"
},
{
"type": "WEB",
"url": "https://github.com/microsoft/kiota/issues/7912"
},
{
"type": "WEB",
"url": "https://github.com/microsoft/kiota/pull/7910"
},
{
"type": "WEB",
"url": "https://github.com/microsoft/kiota/pull/7913"
},
{
"type": "WEB",
"url": "https://github.com/microsoft/kiota/commit/430008e9d700b3fe80f206c672415cfbd8e830e7"
},
{
"type": "WEB",
"url": "https://github.com/microsoft/kiota/commit/de3d18d9fe31ced4ac749728d3a2f94811f59268"
},
{
"type": "PACKAGE",
"url": "https://github.com/microsoft/kiota"
},
{
"type": "WEB",
"url": "https://github.com/microsoft/kiota/releases/tag/v1.34.0"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:H/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "Microsoft Kiota: Path traversal in generated plugin manifest static_template.file reference (percent-encoding bypass)"
}
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.