跳转至

安全与边界

访问矩阵

操作 当前主体与凭据
安装、初始化、服务管理 登录到主机的 ChatArch 用户
本机 put 与 url 同一 ChatArch 用户;不经过 HTTP
新机器远端 put、tree 与 url active ChatEnv chatshare profile 中的 Dufs 写入账号;通过 HTTPS 或 loopback HTTP
已知具体文件 GET/HEAD/Range 匿名客户端;保留跨站 PNG 嵌入
目录 HTML/JSON、搜索、WebDAV 枚举、归档 网关浏览器会话或 Dufs 原生 Basic/Digest
明确分享目录及子目录的只读列表 持有 256-bit 目录 bearer capability 的访客
URL 下载任务和目录分享管理 ChatLogin 浏览器会话所有者 + CSRF;Dufs 精确路径写权限复核
HTTP/WebDAV 上传/PUT 持有共享 Dufs HTTP Auth 凭据的客户端
HTTP 删除 默认不可用
清理、过期、逐文件撤销 当前未实现

该矩阵只适用于 chatshare serve。直连 Dufs 仍保留原生匿名读权限,不能暴露绕过网关的入口。文件 URL 不是密钥;目录门禁不防止猜测文件名,也不提供逐文件撤销。Dufs 现有账号权限及 allow-delete: false 始终保留。

凭据

  • 默认 ChatEnv type:chatshare,关键字段:CHATSHARE_DUFS_USERNAME、CHATSHARE_DUFS_PASSWORD、CHATSHARE_DUFS_BASE_URL。
  • 远端 CLI 从 active profile 或受控进程环境读取这三个字段;它只接受不含 URL 内凭据、查询串或片段的 HTTPS base URL。HTTP 仅允许 loopback,客户端不创建新的实例或平行账号配置。
  • 默认密码变量名:CHATSHARE_DUFS_PASSWORD;CLI 接收变量名,不接收密码值参数。
  • Dufs 需要在启动时读取账号规则,因此密码会存在于 config.yaml;该文件以 0600 写入。
  • 网关登录通过 ChatLogin 异步后端调用 numeric loopback 上的 Dufs 原生 CHECKAUTH + Basic 验证凭据。浏览器只获得 ChatLogin 生成的随机 HttpOnly、SameSite=Strict、Path=/ 会话 cookie 与 /_chatshare/session 返回的每会话 csrf_token;公网 base URL 为 HTTPS 时设置 Secure。鉴权材料仅短暂保留于服务端私有 relay context,按 session digest 索引,不写入文件、不进入 Principal 或公开 session JSON、不建立第二套账号数据库。
  • 每次 cookie 授权请求重新验证 Dufs;登出、过期及密码拒绝都会撤销会话。密码轮换在原有 Dufs 进程识别新密码后生效;网关重启使全部会话失效。原生 Basic/Digest 按原请求转发验证,不把 Digest 重放成其他方法或 URI。
  • 上游 403 表示权限不足,不代表退出登录;只有转发了该会话凭据的请求收到 401 时,代理才撤销会话。匿名具体文件/token 请求失败不影响独立的浏览器会话。既有禁止删除规则继续生效,UI 显示权限错误而不强制登出。
  • 网关 JS 只清除旧 chatshare.dufs.credentials,不把新密码写入 DOM/storage。非网关 Dufs UI 保留旧兼容行为和旧浏览器凭据存储,不能替代服务端门禁。
  • 密码不得出现在 argv、URL、stdout、JSON、access log、unit 文件、README 或测试 fixture。
  • 用户名和密码拒绝 Dufs auth 语法分隔符以及换行,防止规则注入。

网络

  • init 只接受 127.0.0.1、localhost 或 ::1。
  • 0.0.0.0、:: 和 LAN 地址会被拒绝。
  • 当前 CLI 不配置 TLS、Nginx、DNS 或公网入口。
  • 对外发布应由独立部署任务提供可信 Host、TLS、请求大小/速率限制和回滚;不能把直接监听公网当成完成。

文件系统

  • ChatArch 管理目录默认 0700,凭据与状态文件默认 0600。
  • put 拒绝绝对目标、.、..、空组件和根目录逃逸。
  • 本机发布使用同文件系统临时文件和原子替换;未指定 --overwrite 时拒绝覆盖。远端发布先做认证 HEAD 预检并使用分块 PUT,但 Dufs 未证实提供跨独立写入者的原子 create-only 条件写入,不能把预检宣称为全局并发保护。
  • Dufs 的 allow-symlink 与 allow-delete 默认关闭。
  • URL 下载先写入 ChatSharePaths.base/downloads/staging 私有 0600 文件,校验长度、20 GiB 上限和 SHA-256 后才用 fd-relative、无覆盖的同文件系统 hardlink 原子发布;父目录与最终目标不得是 symlink。部署必须让暂存和分享根位于同一文件系统。

URL 下载与目录 capability

  • 每个 URL 跳转都只允许默认端口的 HTTP/HTTPS,无 URL 凭据、控制字符或 fragment;解析出的所有地址都必须是公网地址。连接固定到已验证 IP,同时保留原 Host 与 HTTPS SNI/证书身份;不读取代理环境变量,也不会把 ChatShare Cookie/Authorization 发给来源站。
  • 完整签名 URL 和写入凭据只存在内存;状态和响应只包含安全来源 hostname。重启把未完成任务标为 interrupted 并删除其私有 partial,不会使用持久凭据静默续传。
  • 目录 token 是访问权限,不是普通可公开索引的 ID。公开页面只渲染 Dufs 返回的受限目录条目;目录链接保留在 token 路径,文件链接回到原 URI。撤销不改变具体文件原有匿名读取语义。

明确不提供

  • 分享到期、下载次数和逐文件撤销
  • 多用户/账号所有权和审计
  • OAuth/OIDC、持久浏览器会话或服务端账号所有权
  • S3/object key、CDN 或多节点复制
  • 远程主机注册表和集中式编排

需要上述任一能力时,应先扩展产品和状态模型,而不是把它伪装成 Dufs 配置选项。

网关运行与限制

安装 ChatShare[server]。登录系统由应用自身实现,Nginx 等反向代理只转发,不需要 auth_basic 或 auth_request。chatshare serve 前台监听 127.0.0.1:5001,支持 --bind ::1、--port 和重复 --allowed-host proxy.internal。可导入 create_app(ChatSharePaths.from_home()) 创建 ASGI 应用。非 server CLI 不导入 FastAPI/httpx/uvicorn。root、端口及公网 origin 来自已有实例状态;不添加平行 endpoint/password 环境变量,公网 URL 必须是无子路径的 HTTP(S) origin。

  • 单进程/单 worker;默认会话绝对 TTL 3600 秒、最多 256 个会话、全局滚动 60 秒最多 30 次登录、最多 64 个在途请求。登录 JSON 上限 4096 字节、用户名 128 字符、密码 1024 字符,读取超时 10 秒;上游连接超时 5 秒,普通元数据/读取 I/O 超时 30 秒。认证 PUT/PATCH 保持流式写入且不设上传总时限,等待上游响应的 I/O 空闲超时为 120 秒,连接池等待上限为 30 秒。容量不足返回 429/503。全局限速可能影响其他用户,应由外部代理增加客户端限速。
  • Host 只接受公网 hostname、loopback 与显式 allowed-host;不信任 forwarded headers,不启用 CORS。代理必须保留配置的公网 Origin;登录/登出和 cookie 写入必须带该 Origin 与 X-CSRF-Token: <session csrf_token>,拒绝 null/foreign origin 和跨站 Fetch Metadata。原生显式鉴权客户端不需要此 header。
  • 登录 next 目标必须是安全相对路径字符串。显式畸形值会在凭据验证、会话签发和私有 relay context 替换前被拒绝;缺失 next 时沿用查询值或 /。
  • 匿名仅允许 managed root 内普通文件及 raw、download、cache、token 查询键;token 不能获取目录权限。保守拒绝不合法/歧义百分号编码、控制字符、反斜杠、路径穿越、重复分隔符和 symlink 逃逸,包括双重编码和文件名中的字面百分号。
  • 缺失文件例外:通过严格路径、编码及 root 校验后,无显式 Authorization 的 GET/HEAD 若路径不存在、无尾部斜杠,且没有查询或仅含 raw、download、cache 查询键,则在本地返回空正文、no-store 的 404,不请求 Dufs、不返回目录数据。这保留上传客户端匿名检查目标是否存在的行为。已有目录(包括带点且无尾部斜杠的目录)、根目录、元数据/搜索/归档、token 查询及写入仍受门禁保护;无效显式鉴权不能降级到该 404。
  • 匿名 200/206 必须携带 Dufs 真实文件 Content-Disposition,分类后替换为目录时无 marker 则在发送任何正文前拒绝。304/404/416 不转发上游正文。文件/归档/上传不整体缓冲;响应以 64 KiB 块流式转发,只有已授权 Dufs 管理 HTML 可缓冲,最多 2 MiB,未知 HTML contract 返回 502。不自动重定向或重试。
  • 管理 HTML 必须包含 Dufs index-data 模板和 /__dufs_v<version>__/ 版本化 assets contract;网关注入明确 marker 并改用包内 JS/CSS/favicon,不修改安装中的 Dufs assets。公开资源例外只限网关自有端点和 assets,不按用户文件后缀放行。
  • 所有响应 no-store,Vary 包含 Cookie/Authorization。原始文件响应加 CSP sandbox allow-scripts allow-downloads,不含 allow-same-origin,阻止上传的主动内容读取登录态目录 API,仍允许 PNG 嵌入;部分主动内容预览会受限。可信管理页使用独立限制性 CSP,不加文件 sandbox。页面退出隐藏快照,恢复时重新载入。
  • serve 不安装后台服务、不改代理或账号,也不记录凭据。生产部署使用正常服务监督器,切换前验证目标 Dufs 模板、登录/退出、上传客户端、代理/TLS、Range/哈希与回滚。自动化单元测试采用临时目录和模拟上游,不能替代目标部署的真实验收。