mirror of
https://github.com/whyour/qinglong.git
synced 2025-12-15 08:25:38 +08:00
Add comprehensive sandbox testing documentation
Co-authored-by: whyour <22700758+whyour@users.noreply.github.com>
This commit is contained in:
parent
7abba4c77b
commit
34b06b06f0
125
SANDBOX_TESTING.md
Normal file
125
SANDBOX_TESTING.md
Normal file
|
|
@ -0,0 +1,125 @@
|
||||||
|
# Filesystem Sandbox Testing
|
||||||
|
|
||||||
|
This document describes how to test the filesystem sandbox feature that protects Qinglong from malicious scripts.
|
||||||
|
|
||||||
|
## The Vulnerability (Before Fix)
|
||||||
|
|
||||||
|
The original issue demonstrated that a malicious script could modify critical system files:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const fs = require("fs")
|
||||||
|
const path = require("path")
|
||||||
|
fs.writeFileSync(path.join(__dirname, "..", "..", 'config', 'task_after.sh'), `echo 123`)
|
||||||
|
```
|
||||||
|
|
||||||
|
This would allow the script to inject code that runs after every other script, compromising the entire system.
|
||||||
|
|
||||||
|
## The Fix
|
||||||
|
|
||||||
|
The sandbox intercepts filesystem operations and blocks writes to protected directories:
|
||||||
|
|
||||||
|
### Protected Directories
|
||||||
|
- `/back` - Backend code
|
||||||
|
- `/src` - Frontend code
|
||||||
|
- `/shell` - Shell scripts
|
||||||
|
- `/sample` - Sample files
|
||||||
|
- `/node_modules` - Dependencies
|
||||||
|
- `/data/config` - Configuration files (including task_after.sh, task_before.sh)
|
||||||
|
- `/data/db` - Database files
|
||||||
|
|
||||||
|
### Allowed Directories
|
||||||
|
- `/data/scripts` - User scripts
|
||||||
|
- `/data/log` - Logs
|
||||||
|
- `/data/repo` - Repositories
|
||||||
|
- `/data/raw` - Raw data
|
||||||
|
- `/.tmp` and `/tmp` - Temporary files
|
||||||
|
|
||||||
|
## Testing the Fix
|
||||||
|
|
||||||
|
### Quick Test
|
||||||
|
|
||||||
|
Run the exploit script to verify it's blocked:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /home/runner/work/qinglong/qinglong
|
||||||
|
export QL_DIR=$(pwd)
|
||||||
|
export QL_DATA_DIR=$(pwd)/data
|
||||||
|
|
||||||
|
# Try the exploit
|
||||||
|
cat > data/scripts/test_exploit.js << 'EOF'
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
try {
|
||||||
|
fs.writeFileSync(path.join(__dirname, "..", "..", 'config', 'task_after.sh'), `echo 123`);
|
||||||
|
console.log("❌ VULNERABILITY: Exploit succeeded!");
|
||||||
|
process.exit(1);
|
||||||
|
} catch (error) {
|
||||||
|
if (error.code === 'EACCES') {
|
||||||
|
console.log("✅ SECURE: Exploit blocked!");
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
NODE_OPTIONS="-r ./shell/preload/sandbox.js" node data/scripts/test_exploit.js
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected output: `✅ SECURE: Exploit blocked!`
|
||||||
|
|
||||||
|
### Comprehensive Testing
|
||||||
|
|
||||||
|
The repository includes comprehensive tests:
|
||||||
|
|
||||||
|
1. **Node.js Tests**: Verify that Node.js scripts cannot write to protected paths
|
||||||
|
2. **Python Tests**: Verify that Python scripts cannot write to protected paths
|
||||||
|
3. **Allowed Writes**: Verify that legitimate writes still work
|
||||||
|
4. **Disable Option**: Verify that the sandbox can be disabled when needed
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
### Enable Sandbox (Default)
|
||||||
|
|
||||||
|
The sandbox is enabled by default. No configuration needed.
|
||||||
|
|
||||||
|
### Disable Sandbox (Not Recommended)
|
||||||
|
|
||||||
|
To disable the sandbox:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export QL_DISABLE_SANDBOX=true
|
||||||
|
```
|
||||||
|
|
||||||
|
**Warning**: Disabling the sandbox removes all filesystem protections and allows scripts to modify any file, including critical system files.
|
||||||
|
|
||||||
|
## How It Works
|
||||||
|
|
||||||
|
### Node.js
|
||||||
|
- Loads `shell/preload/sandbox.js` before script execution
|
||||||
|
- Wraps `fs` module methods (writeFile, appendFile, mkdir, unlink, etc.)
|
||||||
|
- Checks paths before allowing write operations
|
||||||
|
- Returns EACCES error for protected paths
|
||||||
|
|
||||||
|
### Python
|
||||||
|
- Loads `shell/preload/sandbox.py` before script execution
|
||||||
|
- Wraps `builtins.open()` for write modes
|
||||||
|
- Wraps `os` module functions (remove, mkdir, rename, etc.)
|
||||||
|
- Wraps `shutil` operations (rmtree, copy, move, etc.)
|
||||||
|
- Wraps `pathlib.Path` methods (write_text, mkdir, unlink, etc.)
|
||||||
|
- Raises PermissionError for protected paths
|
||||||
|
|
||||||
|
## Security Impact
|
||||||
|
|
||||||
|
This fix prevents:
|
||||||
|
- ✅ Modification of task_before.sh and task_after.sh
|
||||||
|
- ✅ Modification of system scripts
|
||||||
|
- ✅ Modification of configuration files
|
||||||
|
- ✅ Injection of code into other scripts
|
||||||
|
- ✅ Compromise of the entire Qinglong installation
|
||||||
|
|
||||||
|
Scripts can still:
|
||||||
|
- ✅ Read any files (read-only access)
|
||||||
|
- ✅ Write to their own directory (/data/scripts)
|
||||||
|
- ✅ Write logs
|
||||||
|
- ✅ Write to temporary directories
|
||||||
|
- ✅ Perform all legitimate operations
|
||||||
Loading…
Reference in New Issue
Block a user