Heuristic:Microsoft Semantic kernel Prompt Injection Safety
| Knowledge Sources | |
|---|---|
| Domains | Security, Prompt_Engineering |
| Last Updated | 2026-02-11 20:00 GMT |
Overview
Security control for prompt template variables: AllowDangerouslySetContent must be explicitly enabled per-variable to allow complex objects or HTML/XML content in prompt templates, preventing injection attacks by default.
Description
Semantic Kernel's prompt template engine sanitizes input variables by default, blocking complex object types and potentially dangerous content (HTML, XML, script fragments) from being injected into prompts. The AllowDangerouslySetContent property on both InputVariable and PromptTemplateConfig must be explicitly set to true to override this protection. This defense-in-depth approach prevents prompt injection attacks where malicious content in user input could alter the AI model's behavior or leak system instructions.
Usage
Use this heuristic when building prompt templates that accept user input, especially in chat applications, agent systems, or any scenario where untrusted data flows into prompt variables. Critical for any implementation using InvokePromptAsync with KernelArguments containing user-supplied values.
The Insight (Rule of Thumb)
- Action: Leave
AllowDangerouslySetContent = false(default) for all user-facing input variables. Only set totruewhen you need to pass pre-validated structured content (e.g., system-generated XML or chat history). - Value: Default is
false(safe). Enable per-variable, not globally. - Trade-off: Safe mode restricts input to simple string types. Enabling dangerous content allows complex objects but requires you to implement your own validation and sanitization layer.
Reasoning
Prompt injection is a well-documented attack vector where user-supplied input manipulates the model's behavior by injecting instructions that override the system prompt. By defaulting to sanitized input, Semantic Kernel provides defense-in-depth: even if a developer forgets to validate user input, the template engine blocks complex payloads. The per-variable granularity allows developers to selectively enable dangerous content only for variables they control (e.g., system-generated context) while keeping user-input variables locked down.
The Handlebars template engine has additional protection: it throws a NotSupportedException for complex type inputs unless dangerous content is explicitly allowed, preventing XML/HTML injection in template rendering.
Code Evidence
Default safe behavior from dotnet/src/SemanticKernel.Core/PromptTemplate/KernelPromptTemplateFactory.cs:28:
public bool AllowDangerouslySetContent { get; init; } = false;
Per-variable and global flag handling from dotnet/src/SemanticKernel.Core/PromptTemplate/KernelPromptTemplate.cs:47-48:
this._allowDangerouslySetContent = allowDangerouslySetContent || promptConfig.AllowDangerouslySetContent;
this._safeBlocks = new HashSet<string>(
promptConfig.InputVariables
.Where(iv => allowDangerouslySetContent || iv.AllowDangerouslySetContent)
.Select(iv => iv.Name));
Usage in tests showing per-variable configuration from dotnet/src/SemanticKernel.UnitTests/PromptTemplate/KernelPromptTemplateTests.cs:578-582:
AllowDangerouslySetContent = true,
InputVariables = [
new() { Name = "system_message", AllowDangerouslySetContent = true },
new() { Name = "user_message", AllowDangerouslySetContent = true },
new() { Name = "user_input", AllowDangerouslySetContent = true }
]