# 🍔 Cheeseburger
The Safe Script Execution Environment.
[](https://crates.io/crates/cheeseburger)
[](https://docs.rs/cheeseburger)
[](https://opensource.org/licenses/MIT)
## Overview
Cheeseburger is a secure script execution library for Rust that lets you run system commands with fine-grained control. I
t provides a sandboxed environment that limits what commands can run and what files they can access.
**Key Features:**
- Command allowlisting
- Working directory confinement
- Path protection with glob patterns
- Command-specific protection overrides
- Comprehensive execution results
## Installation
Add Cheeseburger to your `Cargo.toml`:
```toml
[dependencies]
cheeseburger = "0.1.0"
```
or run:
```shell
cargo add cheeseburger
```
## Quick Start
```rust
use cheeseburger::ScriptExecutor;
fn main() {
// create a script executor a.k.a burger flipper with constraints
let executor = BurgerFlipper::new(
// list of allowed commands
vec!["ls".to_string(), "echo".to_string()],
// pwd that commands are confined to
"/path/to/sandbox",
// global protection patterns that apply to all commands
vec!["**/secret*".to_string(), "**/.env".to_string()],
);
// execute a simple command
match executor.execute("echo Hello world") {
Ok(result) => {
println!("Command output: {}", result.stdout);
println!("Exit code: {}", result.exit_code);
},
Err(err) => {
eprintln!("Error: {}", err);
}
}
}
```
## Features
### Command Allowlisting
Cheeseburger only executes commands that are explicitly allowed:
```rust
let executor = BurgerFlipper::new(
vec!["ls".to_string(), "cat".to_string(), "echo".to_string()],
working_dir,
global_protected_patterns,
);
```
Attempts to run any command not in this list will result in a `CommandNotAllowed` error.
### Working Directory Confinement
Commands can only access files within the specified working directory:
```rust
// this will fail with PathOutsideWorkingDir error
executor.execute("cat /etc/passwd");
```
### Protected Files and Directories
Define global protection patterns that apply to all commands:
```rust
let global_protected = vec![
"**/secret*".to_string(), // protect anything with "secret" in the name
"**/protected/**".to_string(), // protect the "protected" directory and its contents
"**/.env".to_string(), // protect .env files
];
```
### Command-Specific Protection Rules
Set different protection rules for specific commands:
```rust
executor.add_command_protection(
"echo".to_string(),
// cmd-specific protections (in addition to global)
vec!["**/important/**".to_string()],
// cmd-specific overrides (exceptions to global protection)
vec!["**/public_secrets.txt".to_string()],
);
```
### Command Namespace Support
Run commands within namespaces like `fs`:
```rust
executor.execute("fs ls -la");
```
## Security Considerations
Cheeseburger is designed with security in mind, but has some limitations:
- It does not provide full containerization or process isolation
- It does not restrict memory usage, CPU, or other system resources
- It does not handle signals or provide timeout mechanisms
- It validates paths but does not prevent symlink attacks by default
Higher-security environment features will be added in later releases.
## Advanced Usage
### Environment Variables
The `ScriptEnvironment` extension provides environment variable support:
```rust
let mut env = ScriptEnvironment::new(executor);
// set environment variables
env.set_env("PROJECT_DIR", "/tmp/sandbox/project");
env.set_env("LOG_LEVEL", "debug");
// execute scripts with environment variables
env.execute("echo Working in ${PROJECT_DIR} with log level ${LOG_LEVEL}");
```
### Batch Execution
Run multiple commands in sequence:
```rust
let batch = [
"mkdir -p ${PROJECT_DIR}",
"touch ${PROJECT_DIR}/file.txt",
"echo 'Hello world' > ${PROJECT_DIR}/file.txt",
"cat ${PROJECT_DIR}/file.txt",
];
env.execute_batch(&batch);
```
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
## License
This project is licensed under the MIT License - see the LICENSE file for details.