path-safety

作成者: microsoft

サーバー側のパスセキュリティとファイルアクセスエンコーディング規範。ファイルダウンロードルート、Agentツール(ファイル読み取り/ディレクトリ一覧)、データコネクタ/Loader、Workspaceパス操作、サンドボックス設定を記述する際に使用する。

npx skills add https://github.com/microsoft/data-formulator --skill path-safety

name: path-safety description: 服务端路径安全与文件访问编码规范。在编写文件下载路由、Agent 工具(文件读取/目录列出)、数据连接器/Loader、Workspace 路径操作、沙箱配置时使用。

Path Safety — 服务端安全编码规范

来源:docs/dev-guides/8-path-safety.md(正式开发规范)+ design-docs/issues/002-arbitrary-file-read-audit.md(安全审计复核)。 本文档提炼了 6 条必须遵守的编码规范。违反任一条即可能引入路径穿越(LFI)漏洞。


R1. 文件下载:用 ConfinedDir.resolve() + send_file,禁用 send_from_directory

原因:send_from_directory(dir, user_input) 内部会对 user_input 二次解析路径,与前置安全检查形成 TOCTOU 不一致。

# ❌ BAD — 安全检查用 resolved target,发送用原始 filename,两次解析不一致
target = (scratch_dir / filename).resolve()
target.relative_to(scratch_dir.resolve())  # 检查通过
return send_from_directory(str(scratch_dir), filename)  # 再次解析

# ✅ GOOD — 检查和发送用同一个 resolved path
scratch_jail = workspace.confined_scratch
target = scratch_jail.resolve(filename)
return send_file(target)  # 直接用已验证的路径

send_file(Path) 会根据扩展名自动推断 MIME type,无需额外处理。


R2. 路径安全检查:用 ConfinedDir,禁止 str.startswith

原因:str(path).startswith(str(root)) 存在前缀碰撞缺陷(如 /workspace vs /workspace_evil)。

# ❌ BAD
if not str(resolved).startswith(str(root_resolved) + os.sep):
    raise ValueError("escape")

# ✅ GOOD — 统一走 ConfinedDir,内部使用 Path.is_relative_to()
jail = ConfinedDir(root_resolved, mkdir=False)
target = jail.resolve(user_input)

R3. Agent 工具复用 Workspace.confined_*

原因:Agent 工具参数由 LLM 生成,必须视为间接用户输入。不要在工具内手写 Path(root) / rel_path 或 resolve() + relative_to();入口处复用 Workspace 暴露的 ConfinedDir。

# ❌ BAD — 手写路径拼接和校验
def _tool_read_file(self, args, workspace_path):
    target = (workspace_path / rel_path).resolve()
    target.relative_to(workspace_path)

# ✅ GOOD — 入口拿到 ConfinedDir,工具只调用 jail.resolve()
def _execute_tool(self, name, args):
    workspace_jail = self.workspace.confined_root
    scratch_jail = self.workspace.confined_scratch
    return self._tool_read_file(args, workspace_jail)

def _tool_read_file(self, args, workspace_jail):
    target = workspace_jail.resolve(args.get("path", ""))

R4. 优先使用 ConfinedDir,禁止裸路径拼接

原因:Path(root) / user_input 是路径穿越的高频入口。ConfinedDir 封装了三层防御(拒绝绝对路径 → 拒绝 .. 段 → resolve + is_relative_to)。

from data_formulator.security.path_safety import ConfinedDir

# ❌ BAD — 手动拼接 + 手动校验,容易遗漏
local_file = tmp_path / blob_relative_name
local_file.parent.mkdir(parents=True, exist_ok=True)
local_file.write_bytes(data)

# ✅ GOOD — ConfinedDir 自动校验 + 创建父目录
jail = ConfinedDir(tmp_path, mkdir=False)
jail.write(blob_relative_name, data)  # 自动校验 + 写入

已有安全 API 的层次关系

用户输入(filename / relative_path / blob key)
    │
    ▼
safe_data_filename() / secure_filename()     ← 第一层:输入清洗
    │
    ▼
ConfinedDir.resolve()                        ← 第二层:路径约束
    │
    ▼
安全的 Path 对象

使用 Workspace.get_file_path() 的场景不需要手动调用 ConfinedDir,因为它内部已包含等价的校验。


R5. 宿主文件系统访问必须设部署模式守卫

原因:桌面单用户模式允许访问本机文件系统(预期行为),但多用户/云部署下等于开放服务器读权限。

规范:任何新的 Loader / Connector 如果涉及直接读取宿主文件系统(不通过 Workspace API),必须:

  1. 在 data_loader/__init__.py 的 _enforce_deployment_restrictions() 中注册禁用规则
  2. 确保 create_connector() 会拒绝已禁用的类型
# data_loader/__init__.py — 参考 local_folder 的处理方式
def _enforce_deployment_restrictions():
    backend = os.environ.get("WORKSPACE_BACKEND", "local")
    if backend != "local":
        for key in ("local_folder", "your_new_local_loader"):
            if key in DATA_LOADERS:
                del DATA_LOADERS[key]
                DISABLED_LOADERS[key] = f"{key} disabled in multi-user mode"

判断标准:如果 Loader 的构造函数接受一个用户可控的本机路径(如 root_dir),它就需要部署守卫。


R6. 多用户部署必须启用沙箱

原因:not_a_sandbox 模式下 LLM 生成的代码在宿主进程直接执行,可绕过所有路径检查。

app.py 已在启动时检测此配置并输出 logger.critical 警告。新增的沙箱模式或部署脚本应确保:

  • WORKSPACE_BACKEND != "local" 时,SANDBOX 必须为 docker 或 local
  • CI/CD 部署模板中默认设置 SANDBOX=docker

速查:新增代码时的安全检查清单

场景必须做的事
新增文件下载路由用 ConfinedDir.resolve() 得到路径,再 send_file(resolved_path);不用 send_from_directory
新增 Agent 工具(读文件/列目录)入口复用 workspace.confined_root / workspace.confined_scratch,工具内只调用 jail.resolve()
路径包含判断用 ConfinedDir.resolve(),不要手写 Path.is_relative_to() 或 str.startswith()
Path(root) / variable 模式改用 ConfinedDir 或 Workspace.get_file_path()
新增本机文件系统 Loader在 _enforce_deployment_restrictions() 中注册多用户禁用
部署配置多用户模式必须 SANDBOX=docker 或 SANDBOX=local

参考文档

  • docs/dev-guides/8-path-safety.md — 服务端路径安全开发规范
  • design-docs/6-path-safety-confined-dir.md — 剩余未完成实现项状态页
  • design-docs/issues/002-arbitrary-file-read-audit.md — 安全审计复核报告
  • py-src/data_formulator/security/path_safety.py — ConfinedDir 源码

microsoftのその他のスキル

oss-growth
microsoft
OSS成長ハッカーのペルソナ
agent-framework-azure-ai-py
microsoft
Microsoft Agent Framework Python SDK(agent-framework-azure-ai)を使用してAzure AI Foundryエージェントを構築します。AzureAIAgentsProviderを使用した永続的なエージェントの作成、ホスト型ツール(コードインタープリター、ファイル検索、ウェブ検索)の使用、MCPサーバーの統合、会話スレッドの管理、ストリーミング応答の実装時に使用します。関数ツール、構造化出力、マルチツールエージェントをカバーします。
development
airunway-aks-setup
microsoft
AKS上でAI Runwayをセットアップ — ベアクラスターからモデル実行まで。クラスター検証、コントローラーインストール、GPU評価、プロバイダー設定、初回デプロイをカバー。対象: 「AI Runwayのセットアップ」「AKSクラスターのオンボード」「AI Runwayのインストール」「airunway setup」「AKSへのモデルデプロイ」「AKSでのGPU推論」「AKSでのKAITOセットアップ」「AKSでのLLM実行」「AKSでのvLLM」「AKSでのモデルサービング設定」「AI Runwayコントローラー」。
devops
appinsights-instrumentation
microsoft
Azure Application Insightsを使用したWebアプリのインストルメンテーションに関するガイダンス。テレメトリパターン、SDKセットアップ、構成リファレンスを提供します。対象: アプリのインストルメンテーション方法、App Insights SDK、テレメトリパターン、App Insightsとは何か、Application Insightsガイダンス、インストルメンテーション例、APMベストプラクティス。
devops
applicationinsights-web-ts
microsoft
Application Insights JavaScript SDK(@microsoft/applicationinsights-web)を使用してブラウザ/Webアプリを計測します。Real User Monitoring(RUM)— ページビュー、クリック、AJAX/fetch依存関係、例外、カスタムイベント、およびバックエンドのOpenTelemetryトレースに関連付けられたブラウザ側のGenAIエージェントトレースに使用します。SDKローダースクリプトとnpmセットアップ、フレームワーク拡張機能(React、React Native、Angular)、Click Analytics、テレメトリ初期化子、およびブラウザから生成されるエージェント/ツール/モデルスパンのOTel GenAIセマンティック規約をカバーします。
devops
azure-ai-anomalydetector-java
microsoft
Azure AI Anomaly Detector SDK for Javaを使用して異常検出アプリケーションを構築します。単変量/多変量異常検出、時系列分析、またはAIを活用したモニタリングを実装する際に使用します。
development
azure-ai-language-conversations-py
microsoft
azure-ai-language-conversations Python SDKを使用して会話言語理解(CLU)を実装します。ConversationAnalysisClientを使用して会話の意図とエンティティを分析する場合、NLP機能を構築する場合、またはアプリケーションに言語理解を統合する場合に使用します。
development
azure-ai-ml-py
microsoft
Azure Machine Learning SDK v2 for Python。MLワークスペース、ジョブ、モデル、データセット、コンピュート、パイプラインに使用します。 トリガー: 「azure-ai-ml」、「MLClient」、「ワークスペース」、「モデルレジストリ」、「トレーニングジョブ」、「データセット」。
development