mirror of
https://github.com/microsoft/semantic-kernel.git
synced 2026-10-12 02:19:06 +00:00
.Net: Add backslash escaping to redis text search values (#13902)
### Motivation and Context ### Description - Add backslash escaping to redis text search values ### Contribution Checklist <!-- Before submitting this PR, please make sure: --> - [ ] The code builds clean without any errors or warnings - [ ] 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 - [ ] All unit tests pass, and I have added new tests where possible - [ ] I didn't break anyone 😄
This commit is contained in:
@@ -258,8 +258,8 @@ internal class RedisFilterTranslator : FilterTranslatorBase
|
||||
|
||||
private static string SanitizeStringConstant(string value)
|
||||
#if NET
|
||||
=> value.Replace("\"", "\\\"", StringComparison.Ordinal);
|
||||
=> value.Replace("\\", "\\\\", StringComparison.Ordinal).Replace("\"", "\\\"", StringComparison.Ordinal);
|
||||
#else
|
||||
=> value.Replace("\"", "\\\"");
|
||||
=> value.Replace("\\", "\\\\").Replace("\"", "\\\"");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -108,6 +108,58 @@ public sealed class RedisFilterTranslatorTests
|
||||
Assert.Equal("""@Name:{"foo\"bar"}""", result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Equal_with_backslash_in_value()
|
||||
{
|
||||
var result = Translate<TestRecord>(r => r.Name == "foo\\bar");
|
||||
Assert.Equal("""@Name:{"foo\\bar"}""", result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Equal_with_single_backslash()
|
||||
{
|
||||
var result = Translate<TestRecord>(r => r.Name == "\\");
|
||||
Assert.Equal("""@Name:{"\\"}""", result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Equal_with_backslash_quote_injection_attempt()
|
||||
{
|
||||
// Input: \" which should NOT break out of the quoted string
|
||||
var result = Translate<TestRecord>(r => r.Name == "\\\"");
|
||||
Assert.Equal("""@Name:{"\\\""}""", result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Equal_with_backslash_quote_wildcard_injection()
|
||||
{
|
||||
// The specific attack payload: \" | * | \"
|
||||
var result = Translate<TestRecord>(r => r.Name == "\\\" | * | \\\"");
|
||||
Assert.Equal("""@Name:{"\\\" | * | \\\""}""", result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Contains_with_backslash_in_value()
|
||||
{
|
||||
var result = Translate<TestRecord>(r => r.Tags.Contains("foo\\bar"));
|
||||
Assert.Equal("""@Tags:{"foo\\bar"}""", result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Contains_with_backslash_quote_injection_attempt()
|
||||
{
|
||||
var result = Translate<TestRecord>(r => r.Tags.Contains("\\\""));
|
||||
Assert.Equal("""@Tags:{"\\\""}""", result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Any_with_backslash_in_values()
|
||||
{
|
||||
var values = new[] { "a\\b", "c\\d" };
|
||||
var result = Translate<TestRecord>(r => r.Tags.Any(t => values.Contains(t)));
|
||||
Assert.Equal("""@Tags:{"a\\b" | "c\\d"}""", result);
|
||||
}
|
||||
|
||||
private static string Translate<TRecord>(Expression<Func<TRecord, bool>> filter)
|
||||
{
|
||||
var model = BuildModel();
|
||||
|
||||
Reference in New Issue
Block a user