From e225ee02a074cb0c3f1e3be317ed5c3ea9daecaf Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 27 Oct 2026 18:20:32 +0000 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=94=92=20Fix=20command=20injection=20?= =?UTF-8?q?vulnerability=20in=20std.notification=20by=20using=20notify-rus?= =?UTF-8?q?t=20library?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Tcode-Motion <188012755+Tcode-Motion@users.noreply.github.com> --- stdlib/src/notification.rs | 93 ++++++++++++++++++++++++-------------- 1 file changed, 59 insertions(+), 34 deletions(-) diff --git a/stdlib/src/notification.rs b/stdlib/src/notification.rs index b4898fe7..2d32d0a7 100644 --- a/stdlib/src/notification.rs +++ b/stdlib/src/notification.rs @@ -30,30 +30,10 @@ impl StdlibRegistry { } let title = args[0].to_string(); let body = args[1].to_string(); - #[cfg(target_os = "windows")] - { - use base64::Engine; - use std::process::Command; - - let b64_title = base64::engine::general_purpose::STANDARD.encode(title.encode_utf16().flat_map(|c| c.to_le_bytes()).collect::>()); - let b64_body = base64::engine::general_purpose::STANDARD.encode(body.encode_utf16().flat_map(|c| c.to_le_bytes()).collect::>()); - - let script = format!( - "Add-Type -AssemblyName PresentationFramework; [System.Windows.MessageBox]::Show([System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String('{}')), [System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String('{}')))", - b64_body, b64_title - ); - let b64_script = base64::engine::general_purpose::STANDARD.encode(script.encode_utf16().flat_map(|c| c.to_le_bytes()).collect::>()); - - let _ = Command::new("powershell") - .args(["-EncodedCommand", &b64_script]) - .spawn(); - } - #[cfg(not(target_os = "windows"))] - { - let _ = std::process::Command::new("notify-send") - .args([&title, &body]) - .spawn(); - } + let _ = notify_rust::Notification::new() + .summary(&title) + .body(&body) + .show(); Ok(RuntimeValue::Null) }, }), @@ -76,16 +56,10 @@ impl StdlibRegistry { )); } let msg = args[0].to_string(); - #[cfg(target_os = "windows")] - { - let _ = std::process::Command::new("msg").args(["*", &msg]).spawn(); - } - #[cfg(not(target_os = "windows"))] - { - let _ = std::process::Command::new("notify-send") - .args(["Alert", &msg]) - .spawn(); - } + let _ = notify_rust::Notification::new() + .summary("Alert") + .body(&msg) + .show(); Ok(RuntimeValue::Null) }, }), @@ -127,4 +101,55 @@ mod tests { assert_eq!(alert.name(), "alert"); assert_eq!(alert.arity(), 1); } + + #[test] + fn test_notification_execution_capability_denied() { + let mut registry = StdlibRegistry { + modules: std::collections::HashMap::new(), + }; + registry.register_notification(); + let module = registry.get_module("std.notification").unwrap(); + let show = module.exports.get("show").unwrap(); + let alert = module.exports.get("alert").unwrap(); + + let mut config = techscript_runtime::RuntimeConfig::default(); + config.capabilities.remove(&Capability::Process); + let mut ctx = techscript_runtime::RuntimeContext::new(config); + let args_show = vec![ + RuntimeValue::Str("Test Title".to_string()), + RuntimeValue::Str("Test Body".to_string()), + ]; + let res_show = show.call(&mut ctx, args_show); + assert!(res_show.is_err()); + + let args_alert = vec![RuntimeValue::Str("Test Message".to_string())]; + let res_alert = alert.call(&mut ctx, args_alert); + assert!(res_alert.is_err()); + } + + #[test] + fn test_notification_execution_capability_granted() { + let mut registry = StdlibRegistry { + modules: std::collections::HashMap::new(), + }; + registry.register_notification(); + let module = registry.get_module("std.notification").unwrap(); + let show = module.exports.get("show").unwrap(); + let alert = module.exports.get("alert").unwrap(); + + let mut config = techscript_runtime::RuntimeConfig::default(); + config.capabilities.insert(Capability::Process); + let mut ctx = techscript_runtime::RuntimeContext::new(config); + + let args_show = vec![ + RuntimeValue::Str("Title; calc.exe".to_string()), + RuntimeValue::Str("Body; rm -rf /".to_string()), + ]; + let res_show = show.call(&mut ctx, args_show); + assert!(res_show.is_ok()); + + let args_alert = vec![RuntimeValue::Str("Alert Message; id".to_string())]; + let res_alert = alert.call(&mut ctx, args_alert); + assert!(res_alert.is_ok()); + } } From 827990af4683462f6978344eb3a8a5ba9ddba64b Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 27 Oct 2026 20:49:07 +0000 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=94=92=20Fix=20command=20injection=20?= =?UTF-8?q?vulnerability=20in=20std.notification=20by=20using=20notify-rus?= =?UTF-8?q?t=20library?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Tcode-Motion <188012755+Tcode-Motion@users.noreply.github.com>