ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

LangGraph Checkpoint 如何配置 LANGGRAPH_STRICT_MSGPACK 限制反序列化类型以防止代码执行?

LangGraph Checkpoint 如何配置 LANGGRAPH_STRICT_MSGPACK 限制反序列化类型以防止代码执行? LangGraph Checkpoint 如何配置 LANGGRAPH_STRICT_MSGPACK 限制反序列化类型以防止代码执行【免费下载链接】langgraphBuild resilient agents.项目地址: https://gitcode.com/GitHub_Trending/la/langgraph如果你的 LangGraph 应用使用 checkpointer 把图状态持久化到 SQLite 或 Postgres而数据库文件/实例可能被外部写入那么默认的反序列化行为存在一个真实风险jsonplus.py中的安全警告明确写道序列化器不应处理不受信任的 Python 对象——“If an attacker can write directly to your checkpoint database, they may be able to trigger code execution when data is deserialized.”如果攻击者能直接写入你的 checkpoint 数据库他们可能在数据被反序列化时触发代码执行。_msgpack.py的模块文档更进一步说明不启用严格模式时checkpoint 数据中存储的任何 Python 可调用对象都会在加载时被导入并执行。这篇文章的任务只有一个通过LANGGRAPH_STRICT_MSGPACKtrue环境变量或JsonPlusSerializer的allowed_msgpack_modules参数把 checkpoint 反序列化限制在已知安全的类型范围内并验证限制确实生效。内容适用于langgraph-checkpoint的默认序列化实现以及 libs/checkpoint-sqlite/README.md 和 libs/checkpoint-postgres/README.md 两个 README 的 Security 章节中给出相同安全建议的 SQLite/Postgres 集成。为什么默认行为需要收紧libs/checkpoint/README.md 的 Serde 一节给出了官方提示Checkpoint deserialization security:By default the serializer allows any Python type found in checkpoint data. New applications should set the environment variableLANGGRAPH_STRICT_MSGPACKtrueor pass an explicitallowed_msgpack_moduleslist toJsonPlusSerializerto restrict deserialization to known-safe types.也就是说默认permissive模式下checkpoint 数据里出现什么类型JsonPlusSerializer就尝试还原什么类型只有类型不在安全清单内时打一条“未来版本会拦截”的警告但仍会正常反序列化。对可信环境这没问题一旦数据库可被第三方写入就变成代码执行入口。依赖安装按各包 README 的 Quick Install 进行例如uv add langgraph-checkpoint、uv add langgraph-checkpoint-sqlite或uv add langgraph-checkpoint-postgres。方式一设置环境变量 LANGGRAPH_STRICT_MSGPACK在启动应用进程前设置export LANGGRAPH_STRICT_MSGPACKtrue取值解析逻辑在 libs/checkpoint/langgraph/checkpoint/serde/_msgpack.py 中STRICT_MSGPACK_ENABLED os.getenv(LANGGRAPH_STRICT_MSGPACK, false).lower() in ( 1, true, yes, )即1、true、yes不区分大小写都启用严格模式默认值false保持宽松模式。注意这个变量是在模块加载时读取一次必须在进程首次导入langgraph.checkpoint之前通过环境生效而不是在运行中动态改变把它写进部署环境容器环境变量、启动脚本、CI 配置是最可靠的做法。启用后反序列化只允许SAFE_MSGPACK_TYPES中列出的类型覆盖以下类别datetime 系列datetime、date、time、timedelta、timezone、uuid.UUID、decimal.Decimal集合类型set、frozenset、collections.dequeipaddress的 IPv4/IPv6 各类型、pathlib.Path及其变体、zoneinfo.ZoneInfo、re.compileLangChain 消息类型HumanMessage、AIMessage、SystemMessage、ToolMessage、Document等LangGraph 自身类型Send、Command、Interrupt、StateSnapshot、PregelTask等方法调用另有一份独立的白名单SAFE_MSGPACK_METHODS目前仅允许datetime.datetime.fromisoformat一个调用。方式二给 JsonPlusSerializer 显式传 allowed_msgpack_modules环境变量是进程级开关如果只想收紧某一个 checkpointer或者在严格模式之外再补充自定义类型可以在构造JsonPlusSerializer时传allowed_msgpack_modules。构造器在 libs/checkpoint/langgraph/checkpoint/serde/jsonplus.py 中的行为是传值效果None且不设环境变量严格模式只允许SAFE_MSGPACK_TYPES显式列表(模块, 类名)元组或类型对象只允许安全类型 列表中的类型True宽松模式全部放行对未注册类型打警告默认行为不传默认环境变量开启则等同None严格否则等同True宽松并告警以 SQLite 为例仓库测试基线 libs/langgraph/tests/conftest_checkpointer.py 展示的模式是先创建 checkpointer再替换其serdefrom langgraph.checkpoint.sqlite import SqliteSaver from langgraph.checkpoint.serde.jsonplus import JsonPlusSerializer with SqliteSaver.from_conn_string(checkpoints.db) as checkpointer: # 严格模式 追加自定义类型把元组替换为你实际的 (模块路径, 类名) checkpointer.serde JsonPlusSerializer( allowed_msgpack_modules[ (myapp.state, MyState), (myapp.state, InnerModel), ] ) # ...后续 put / get / list 正常进行上面的元组格式与 libs/checkpoint/tests/test_jsonplus.py 中test_msgpack_allowlist_silences_warning的用法一致示例里的myapp.state、MyState需要替换成你的实际模块路径和类名。若只想启用纯严格模式而不加任何自定义类型仓库测试使用的写法是JsonPlusSerializer(allowed_msgpack_modulesNone)。已经持有 serializer 实例时也可以用with_msgpack_allowlist(extra)返回一个合并了额外白名单的新实例而不会修改原实例。验证配置是否生效仓库测试 libs/checkpoint/tests/test_jsonplus.py 覆盖了两种模式的行为可以照它的思路写一段自检脚本。以下脚本不依赖数据库直接验证序列化层from pydantic import BaseModel from langgraph.checkpoint.serde.jsonplus import JsonPlusSerializer class DemoModel(BaseModel): value: str serde JsonPlusSerializer() obj DemoModel(valuedemo) dumped serde.dumps_typed(obj) result serde.loads_typed(dumped) print(type(result).__name__, result)把DemoModel理解成你图状态里用到的任意自定义 Pydantic 模型。按测试给出的行为判断结果这是仓库测试断言的模式不是固定输出未设环境变量宽松模式日志中出现Deserializing unregistered type ...的警告内容提示 “This will be blocked in a future version. Set LANGGRAPH_STRICT_MSGPACKtrue to block now, or add to allowed_msgpack_modules to allow explicitly”且loads_typed返回的对象仍等于原始模型——数据能还原风险窗口仍在。对应测试test_msgpack_pydantic_warns_by_default。已设LANGGRAPH_STRICT_MSGPACKtrue日志中出现Blocked deserialization of ... - not in allowed_msgpack_modules的警告且反序列化结果是该对象的 dict 形式测试断言result obj.model_dump()而不再是原模型实例。对应测试test_msgpack_env_strict_default。看到 “blocked” 日志并得到 dict 结果说明严格模式已拦截未注册类型。类型已加入allowed_msgpack_modules无警告正常还原为原类型test_msgpack_allowlist_silences_warning。对真实应用做端到端确认时用 SQLite/Postgres 的 checkpointer 正常执行一次put/get状态里只含安全类型时应当无 blocked 警告若某个业务类型被拦截警告日志会直接给出应加入白名单的元组格式按提示把(模块, 类名)补进allowed_msgpack_modules即可。边界与限制被拦截的类型会以 dict或降级形式落回图状态而不是抛错中断如果你的业务逻辑依赖强类型读取该字段需要在白名单中显式放行它。旧格式兼容jsonplus.py中_is_safe_json_type的文档说明msgpack 迁移之前写入的旧 “json” 格式 checkpoint只要涉及的是SAFE_MSGPACK_TYPES内的类型就能绕过allowed_json_modules检查直接恢复不需要为旧数据额外配置白名单。同一类型的警告在进程内去重每种类型只提示一次所以日志里只看到一条 blocked/unregistered 不代表只影响一个值。Postgres 侧若手动创建连接传给PostgresSaver仍要遵守 libs/checkpoint-postgres/README.md 的要求连接需带autocommitTrue和row_factorydict_row首次使用调用.setup()——这些与严格模式无关但属于同一 README 中要求一并满足的运行条件。JsonPlusSerializer本身定位是在BaseCheckpointSaver内部、Pregel 循环中被调用的组件文档明确提示不要直接拿它处理不受信任的 Python 对象严格模式是限制类型范围不是通用沙箱。完成配置后判断标准很直接宽松模式下未注册类型“警告但放行”严格模式下变为“blocked 日志 降级为 dict”。两者都确认后你的 checkpoint 数据即使被写入恶意类型也不会在加载时触发代码导入执行。【免费下载链接】langgraphBuild resilient agents.项目地址: https://gitcode.com/GitHub_Trending/la/langgraph创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表