pipeline-sdlc/wwwroot/workspace_edit.xterm
ymq 790d8edb12 security: workspace_edit.xterm 未登录直接拒绝,去掉匿名回退 admin
此前 'if not uid: uid = user-01' 把未登录者当成 admin:结合 RBAC 通配授权,
匿名可拿到 admin 工作空间的编辑器进程,读写工作空间全部源码与 env/*.json(含 DB 密码)。
2026-08-25 14:47:05 +08:00

84 lines
2.5 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 到 /homevi 用相对路径)
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