Skip to content

Conversation

@dmytrostruk
Copy link
Member

@dmytrostruk dmytrostruk commented Aug 21, 2025

Motivation and Context

Resolves: #11821

Today, the encoding of template arguments is performed only if argument type is string. In case of custom type, anonymous type or collection - the encoding is not performed.

This PR contains changes to throw an exception in case if encoding is enabled but complex type is used. In case of complex type, the encoding should be performed manually according to business logic and automatic encoding should be explicitly disabled.

This enforces stricter, but more secure template rendering rules.

Note: this is a breaking change for customers who use Handlebars or Liquid template with complex type arguments. Code changes are required when initializing template arguments:

var arguments = new KernelArguments()
{
    { "customer", new
        {
-             firstName = userInput.FirstName,
-             lastName = userInput.LastName,
+             firstName = HttpUtility.HtmlEncode(userInput.FirstName),
+             lastName = HttpUtility.HtmlEncode(userInput.LastName),
        }
    }
};

var templateFactory = new LiquidPromptTemplateFactory();
var promptTemplateConfig = new PromptTemplateConfig()
{
    TemplateFormat = "liquid"
+   InputVariables = new()
+   {
+       // We set AllowDangerouslySetContent to 'true' because each property of this argument is encoded manually. 
+       new() { Name = "customer", AllowDangerouslySetContent = true },
+   }
};

var promptTemplate = templateFactory.Create(promptTemplateConfig);
var renderedPrompt = await promptTemplate.RenderAsync(kernel, arguments); 

Contribution Checklist

@dmytrostruk dmytrostruk self-assigned this Aug 21, 2025
@dmytrostruk dmytrostruk added the PR: breaking change Pull requests that introduce breaking changes label Aug 21, 2025
@dmytrostruk dmytrostruk requested a review from a team as a code owner August 21, 2025 00:27
@moonbox3 moonbox3 added .NET Issue or Pull requests regarding .NET code kernel Issues or pull requests impacting the core kernel labels Aug 21, 2025
@dmytrostruk dmytrostruk requested a review from a team as a code owner August 21, 2025 23:31
@moonbox3 moonbox3 added the python Pull requests for the Python Semantic Kernel label Aug 21, 2025
@github-actions github-actions bot changed the title .Net: Updated encoding logic in prompt templates Python: .Net: Updated encoding logic in prompt templates Aug 21, 2025
@moonbox3
Copy link
Collaborator

moonbox3 commented Aug 22, 2025

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
kernel.py2295874%149, 160, 164, 320–321, 323, 405, 411–412, 416–417, 470–474, 476–477, 490–499, 501, 503–504, 506–526, 528–533
agents/orchestration
   magentic.py3085781%123–125, 257, 394, 475, 480, 482, 489, 493, 495, 553–554, 556–557, 563, 565–566, 570, 598, 602, 612–614, 617, 622–627, 649, 661–662, 664, 669, 673–674, 676, 678–679, 684, 694–695, 698, 702–703, 709–710, 712, 740, 742, 751–755
functions
   kernel_function_from_prompt.py1782486%117, 174–175, 189, 213–215, 219–220, 222, 225, 227–229, 233–234, 236, 239, 241, 247–248, 262, 288, 382
prompt_template
   prompt_template_base.py44393%115, 119, 123
TOTAL26930465182% 

Python Unit Test Overview

Tests Skipped Failures Errors Time
3684 22 💤 0 ❌ 0 🔥 1m 39s ⏱️

@dmytrostruk dmytrostruk added this pull request to the merge queue Aug 25, 2025
@dmytrostruk dmytrostruk removed this pull request from the merge queue due to a manual request Aug 25, 2025
@dmytrostruk dmytrostruk enabled auto-merge August 25, 2025 18:50
@dmytrostruk dmytrostruk added this pull request to the merge queue Aug 25, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Aug 25, 2025
jcruzmot-te pushed a commit to thousandeyes/aia-semantic-kernel that referenced this pull request Sep 15, 2025
…2983)

### Motivation and Context

<!-- Thank you for your contribution to the semantic-kernel repo!
Please help reviewers and future users, providing the following
information:
  1. Why is this change required?
  2. What problem does it solve?
  3. What scenario does it contribute to?
  4. If it fixes an open issue, please link to the issue here.
-->

Resolves: microsoft#11821

Today, the encoding of template arguments is performed only if argument
type is `string`. In case of custom type, anonymous type or collection -
the encoding is not performed.

This PR contains changes to throw an exception in case if encoding is
enabled but complex type is used. In case of complex type, the encoding
should be performed manually according to business logic and automatic
encoding should be explicitly disabled.

This enforces stricter, but more secure template rendering rules.

**Note**: this is a breaking change for customers who use Handlebars or
Liquid template with complex type arguments. Code changes are required
when initializing template arguments:
```diff
var arguments = new KernelArguments()
{
    { "customer", new
        {
-             firstName = userInput.FirstName,
-             lastName = userInput.LastName,
+             firstName = HttpUtility.HtmlEncode(userInput.FirstName),
+             lastName = HttpUtility.HtmlEncode(userInput.LastName),
        }
    }
};

var templateFactory = new LiquidPromptTemplateFactory();
var promptTemplateConfig = new PromptTemplateConfig()
{
    TemplateFormat = "liquid"
+   InputVariables = new()
+   {
+       // We set AllowDangerouslySetContent to 'true' because each property of this argument is encoded manually. 
+       new() { Name = "customer", AllowDangerouslySetContent = true },
+   }
};

var promptTemplate = templateFactory.Create(promptTemplateConfig);
var renderedPrompt = await promptTemplate.RenderAsync(kernel, arguments); 
```

### Contribution Checklist

<!-- Before submitting this PR, please make sure: -->

- [x] The code builds clean without any errors or warnings
- [x] The PR follows the [SK Contribution
Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md)
and the [pre-submission formatting
script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#development-scripts)
raises no violations
- [x] All unit tests pass, and I have added new tests where possible
- [ ] I didn't break anyone 😄
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kernel Issues or pull requests impacting the core kernel .NET Issue or Pull requests regarding .NET code PR: breaking change Pull requests that introduce breaking changes python Pull requests for the Python Semantic Kernel

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python: Bug: Argument Escaping in Semantic Kernel Prompt Templates

6 participants