diff --git a/stdlib/src/process.rs b/stdlib/src/process.rs index 590d8a8c..4343ba1f 100644 --- a/stdlib/src/process.rs +++ b/stdlib/src/process.rs @@ -38,7 +38,18 @@ fn process_run( RuntimeValue::List { items, .. } => { let mut list = Vec::new(); for item in items.borrow().iter() { - list.push(item.try_into_string()?); + let s = item.try_into_string()?; + if s.contains('\0') { + return Err(RuntimeError::new( + RuntimeErrorKind::InvalidOperation( + "Security policy violation: Null bytes in command arguments are denied" + .to_string(), + ), + None, + None, + )); + } + list.push(s); } list } diff --git a/stdlib/tests/stdlib_tests.rs b/stdlib/tests/stdlib_tests.rs index 05c13a8c..c99f1d8b 100644 --- a/stdlib/tests/stdlib_tests.rs +++ b/stdlib/tests/stdlib_tests.rs @@ -701,6 +701,25 @@ fn test_system_diagnostics_and_process_execution() { } else { panic!("run did not return a Map"); } + + // 3. Verify process.run rejects null bytes in arguments + let null_arg_res = run.call( + &mut ctx, + vec![ + RuntimeValue::Str(cmd.to_string()), + RuntimeValue::List { + items: Rc::new(RefCell::new(vec![RuntimeValue::Str( + "hello\0world".to_string(), + )])), + is_const: false, + }, + ], + ); + assert!(null_arg_res.is_err()); + assert!(null_arg_res + .unwrap_err() + .to_string() + .contains("Security policy violation: Null bytes in command arguments are denied")); } #[test]