此前 'if not uid: uid = user-01' 把未登录者当成 admin:结合 RBAC 通配授权, 匿名可拿到 admin 工作空间的编辑器进程,读写工作空间全部源码与 env/*.json(含 DB 密码)。
84 lines
2.5 KiB
Plaintext
84 lines
2.5 KiB
Plaintext
import os
|
||
import shlex
|
||
import shutil
|
||
|
||
file_id = (params_kw or {}).get('id', '').strip()
|
||
|
||
uid = await get_user()
|
||
if not uid:
|
||
# 安全:未登录直接拒绝。此前回退成 'user-01'(admin) —— 结合 RBAC 通配授权,
|
||
# 未登录者可拿到 admin 工作空间的编辑器进程(bwrap 沙箱内仍可读写工作空间
|
||
# 全部源码与 env/*.json,后者含 DB 密码)。禁止匿名回退。
|
||
r = DictObject()
|
||
r.host = 'localhost'
|
||
r.username = 'pipeline'
|
||
r.cmdargs = ['echo 未登录,拒绝访问']
|
||
r.noinput = True
|
||
return r
|
||
|
||
session_id = (params_kw or {}).get('session_id', '') or ''
|
||
|
||
dbname = get_module_dbname('pipeline-sdlc')
|
||
|
||
async with DBPools().sqlorContext(dbname) as sor:
|
||
project_dir, _ = await get_project_dir(sor, uid, session_id)
|
||
space_dir, _ = await get_space_dir(sor, uid, session_id)
|
||
|
||
if not file_id or not space_dir:
|
||
r = DictObject()
|
||
r.host = 'localhost'
|
||
r.username = 'pipeline'
|
||
r.cmdargs = ['echo 未指定文件']
|
||
return r
|
||
|
||
full_path = resolve_workspace_path(project_dir, space_dir, file_id)
|
||
|
||
# 路径穿越校验
|
||
real_ws = os.path.realpath(space_dir)
|
||
real_full = os.path.realpath(full_path)
|
||
if not real_full.startswith(real_ws + os.sep):
|
||
r = DictObject()
|
||
r.host = 'localhost'
|
||
r.username = 'pipeline'
|
||
r.cmdargs = ['echo 非法路径']
|
||
return r
|
||
|
||
# 相对 space_dir 的路径(bwrap 挂载 space_dir 到 /home,vi 用相对路径)
|
||
rel_path = os.path.relpath(full_path, space_dir)
|
||
|
||
# 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'
|
||
|
||
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(rel_path)
|
||
)
|
||
r.cmdargs = [cmd]
|
||
return r
|