Implemented
Bashkit uses fail-rs for fault injection security testing. This enables systematic testing of error handling paths and resource limit enforcement under failure conditions.
Fail points are disabled by default and have zero runtime overhead when disabled.
# Run security tests
cargo test --features failpoints security_
# Run with single thread to avoid race conditions
cargo test --features failpoints security_ -- --test-threads=1| Fail Point | Actions | Security Test Purpose |
|---|---|---|
limits::tick_command |
skip_increment, force_overflow, corrupt_high |
Test command limit bypass resistance |
limits::tick_loop |
skip_check, reset_counter |
Test loop limit bypass resistance |
limits::push_function |
skip_check, corrupt_depth |
Test recursion limit bypass resistance |
| Fail Point | Actions | Security Test Purpose |
|---|---|---|
fs::read_file |
io_error, permission_denied, corrupt_data |
Test read failure handling |
fs::write_file |
io_error, disk_full, permission_denied, partial_write |
Test write failure handling |
| Fail Point | Actions | Security Test Purpose |
|---|---|---|
interp::execute_command |
panic, error, exit_nonzero |
Test command execution failure handling |
#[tokio::test]
async fn test_resource_limit_bypass() {
// Configure fail point
fail::cfg("limits::tick_command", "return(skip_increment)").unwrap();
// Run code that should be affected
let result = run_script("echo hello").await;
// Always clean up
fail::cfg("limits::tick_command", "off").unwrap();
// Assert expected behavior
assert!(/* ... */);
}From fail-rs documentation:
| Action | Syntax | Description |
|---|---|---|
return |
return(value) |
Return early with value |
panic |
panic(msg) |
Panic with message |
print |
print(msg) |
Print message |
sleep |
sleep(ms) |
Sleep for milliseconds |
pause |
pause |
Pause until unpaused |
yield |
yield |
Yield to scheduler |
# 10% probability
FAILPOINTS="limits::tick_command=10%return(skip_increment)"
# First 5 times only
FAILPOINTS="limits::tick_command=5*return(skip_increment)"
# Combined: 10% probability, max 3 times
FAILPOINTS="limits::tick_command=3*10%return(skip_increment)"Test that resource limits cannot be bypassed through:
- Counter corruption
- Check skipping
- Counter overflow/underflow
Test graceful handling of:
- I/O errors
- Permission denied
- Disk full
- Partial writes
- Data corruption
Test behavior under:
- Execution errors
- Panic recovery (where applicable)
- Unexpected exit codes
- Import the macro:
#[cfg(feature = "failpoints")]
use fail::fail_point;- Add fail point at critical location:
#[cfg(feature = "failpoints")]
fail_point!("module::function", |action| {
match action.as_deref() {
Some("failure_mode") => {
return Err(/* error */);
}
_ => {}
}
Ok(()) // Default: continue normal execution
});-
Document in this spec.
-
Add tests in
tests/security_failpoint_tests.rs.
- Always clean up: Call
fail::cfg("name", "off")after tests. - Single-threaded tests: Use
--test-threads=1for fail point tests due to global state. - Document actions: List all supported actions in code comments and this spec.
- Test both paths: Test that fail points affect behavior AND that normal operation works without them.
The JavaScript/TypeScript bindings have a dedicated security test suite at
crates/bashkit-js/__test__/security.spec.ts. These tests cover both
white-box (targeting known internals) and black-box (adversarial inputs)
scenarios across 18 categories:
- Resource limit enforcement (TM-DOS)
- Output truncation (TM-DOS)
- Sandbox escape prevention (TM-ESC)
- VFS security — path traversal, file count, nesting, filename limits (TM-DOS, TM-INJ)
- Instance isolation (TM-ISO)
- Error message safety (TM-INT)
- TypeScript wrapper injection prevention (TM-INJ)
- Adversarial script inputs — null bytes, deep nesting, expansion bombs
- Unicode & encoding attacks (TM-UNI)
- Injection via constructor options (TM-INJ)
- Concurrency & cancellation (TM-DOS)
- Async API security
- BashTool metadata safety
- Bash feature abuse — traps, special variables, /dev/tcp
- Mounted files security
- Rapid instance creation/destruction
- Edge case inputs
- Async factory security
# Run JS security tests
cd crates/bashkit-js && npm testcrates/bashkit/tests/security_failpoint_tests.rs- Fail-point security testscrates/bashkit/tests/threat_model_tests.rs- Threat model tests (51 tests)crates/bashkit/tests/builtin_error_security_tests.rs- Builtin error security tests (39 tests, includes TM-INT-003)crates/bashkit-js/__test__/security.spec.ts- JavaScript security tests (90+ tests, 18 categories)crates/bashkit/src/limits.rs- Resource limit fail pointscrates/bashkit/src/fs/memory.rs- Filesystem fail pointscrates/bashkit/src/interpreter/mod.rs- Interpreter fail points, panic catchingcrates/bashkit/src/builtins/system.rs- Hardcoded system builtinsspecs/threat-model.md- Threat model specification