3.6 KiB
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:
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/.tmpand/tmp- Temporary files
Testing the Fix
Quick Test
Run the exploit script to verify it's blocked:
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:
- Node.js Tests: Verify that Node.js scripts cannot write to protected paths
- Python Tests: Verify that Python scripts cannot write to protected paths
- Allowed Writes: Verify that legitimate writes still work
- 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:
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.jsbefore script execution - Wraps
fsmodule methods (writeFile, appendFile, mkdir, unlink, etc.) - Checks paths before allowing write operations
- Returns EACCES error for protected paths
Python
- Loads
shell/preload/sandbox.pybefore script execution - Wraps
builtins.open()for write modes - Wraps
osmodule functions (remove, mkdir, rename, etc.) - Wraps
shutiloperations (rmtree, copy, move, etc.) - Wraps
pathlib.Pathmethods (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