diff --git a/wwwroot/workspace_edit.xterm b/wwwroot/workspace_edit.xterm index 1fc2e3c..aec918a 100644 --- a/wwwroot/workspace_edit.xterm +++ b/wwwroot/workspace_edit.xterm @@ -1,5 +1,6 @@ import os import shlex +import shutil file_id = (params_kw or {}).get('id', '').strip() @@ -45,8 +46,38 @@ if not real_full.startswith(real_ws + os.sep): r.cmdargs = ['echo 非法路径'] return r +# bwrap 沙箱路径(不存在则拒绝终端,安全优先,不给完整 shell) +bwrap = shutil.which('bwrap') +if not bwrap and os.path.exists('/d/pipeline/pipeline-app/bin/bwrap'): + bwrap = '/d/pipeline/pipeline-app/bin/bwrap' + r = DictObject() r.host = 'localhost' r.username = 'pipeline' -r.cmdargs = ['vi ' + shlex.quote(full_path)] + +if not bwrap: + r.cmdargs = ['echo 沙箱不可用,已拒绝终端访问'] + return r + +# bwrap 沙箱:只暴露 workspace(挂载到 /home 可写)+ 只读系统目录, +# 隔离 user/pid/ipc/uts/net,防 rm -rf /、sudo 提权、越界访问、网络攻击 +cmd = ( + bwrap + + ' --unshare-user --unshare-pid --unshare-ipc --unshare-uts --unshare-net' + ' --die-with-parent' + ' --ro-bind /usr /usr' + ' --ro-bind /bin /bin' + ' --ro-bind /sbin /sbin' + ' --ro-bind /lib /lib' + ' --ro-bind /lib64 /lib64' + ' --ro-bind /etc /etc' + ' --proc /proc' + ' --dev /dev' + ' --tmpfs /tmp' + ' --bind ' + shlex.quote(real_ws) + ' /home' + ' --chdir /home' + ' --setenv HOME /home' + ' -- vi ' + shlex.quote(file_id) +) +r.cmdargs = [cmd] return r