Skip to content

Python: fix(core): restrict unpickler module-prefix allowlist to types only - #5923

Merged
Evan Mattson (moonbox3) merged 4 commits into
microsoft:mainfrom
White-Mouse:fix/restricted-unpickler-non-type-globals
Jul 30, 2026
Merged

Python: fix(core): restrict unpickler module-prefix allowlist to types only#5923
Evan Mattson (moonbox3) merged 4 commits into
microsoft:mainfrom
White-Mouse:fix/restricted-unpickler-non-type-globals

Conversation

@White-Mouse

@White-Mouse HaoJun (White-Mouse) commented May 18, 2026

Copy link
Copy Markdown
Contributor

Motivation & Context

The restricted checkpoint decoder allows framework and OpenAI SDK types by module prefix. The previous implementation returned any global from those modules, and the allowlisted builtins.getattr could also traverse attributes on an allowed type. Together, those behaviors allowed a crafted pickle to reach a non-type callable such as _RestrictedUnpickler.__init__.__globals__["pickle"].loads before the post-deserialization type check.

This change tightens that defense-in-depth path while preserving the checkpoint format and supported type reconstruction.

Description & Review Guide

  • What are the major changes? Package-prefix and caller-supplied allowlist entries must resolve to a type. During restricted unpickling, builtins.getattr is replaced with a resolver that only permits type-to-type attribute lookup. Regression tests cover non-type globals, legitimate nested-type lookup, and the full getattr/__globals__/inner-pickle.loads chain.
  • What is the impact of these changes? Valid built-in, framework, OpenAI SDK, explicitly allowed, and nested type reconstruction remains supported. Non-type globals and non-type attribute traversal are rejected with pickle.UnpicklingError.
  • What do you want reviewers to focus on? Please review the compatibility boundary of the restricted getattr replacement and whether the regression coverage captures the expected nested-type reconstruction cases.

Related Issue

Fixes #7432

Contribution Checklist

  • The code builds clean without any errors or warnings
  • All unit tests pass, and I have added new tests where possible
  • The PR follows the Contribution Guidelines
  • This PR is linked to an issue and there is no other open PR for this issue (see Related Issue above).
  • This is not a breaking change. If it is a breaking change, add the breaking change label (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and title prefix in sync automatically.

Copilot AI review requested due to automatic review settings May 18, 2026 16:39
@moonbox3 Evan Mattson (moonbox3) added the python Usage: [Issues, PRs], Target: Python label May 18, 2026
@github-actions github-actions Bot changed the title fix(core): restrict unpickler module-prefix allowlist to types only Python: fix(core): restrict unpickler module-prefix allowlist to types only May 18, 2026
@White-Mouse

Copy link
Copy Markdown
Contributor Author

@microsoft-github-policy-service agree

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Tightens the Python checkpoint restricted unpickling boundary by preventing agent_framework.* and openai.types.* module-prefix allowlisting from returning non-type globals (e.g., functions/modules), mitigating gadget chains that can pivot via builtins.getattr.

Changes:

  • Updates _RestrictedUnpickler.find_class to resolve globals under allowed prefixes and permit them only if they are actual type objects.
  • Adds a dedicated UnpicklingError message for blocked non-type globals from allowed prefixes.

Comment thread python/packages/core/agent_framework/_workflows/_checkpoint_encoding.py Outdated
Comment thread python/packages/core/agent_framework/_workflows/_checkpoint_encoding.py Outdated
Comment thread python/packages/core/agent_framework/_workflows/_checkpoint_encoding.py Outdated
@White-Mouse
HaoJun (White-Mouse) force-pushed the fix/restricted-unpickler-non-type-globals branch from f514068 to 04d425a Compare June 2, 2026 16:52
@moonbox3

Copy link
Copy Markdown
Contributor

HaoJun (@White-Mouse) thanks for your contribution. Is there an open issue we can link to? Additionally, please help to fix the merge conflict.

@White-Mouse
HaoJun (White-Mouse) force-pushed the fix/restricted-unpickler-non-type-globals branch from 04d425a to b996da1 Compare July 10, 2026 05:17
@github-actions

github-actions Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
packages/core/agent_framework/_workflows
   _checkpoint_encoding.py110298%160, 327
TOTAL46675448690% 

Python Unit Test Overview

Tests Skipped Failures Errors Time
9614 34 💤 0 ❌ 0 🔥 2m 35s ⏱️

Comment thread python/packages/core/agent_framework/_workflows/_checkpoint_encoding.py Outdated
@White-Mouse
HaoJun (White-Mouse) force-pushed the fix/restricted-unpickler-non-type-globals branch from e255fd1 to 1bc4077 Compare July 14, 2026 12:56
@White-Mouse
HaoJun (White-Mouse) force-pushed the fix/restricted-unpickler-non-type-globals branch from 1bc4077 to 9dd038e Compare July 15, 2026 04:50
@moonbox3

Copy link
Copy Markdown
Contributor

Quick ping on this - let me know if you need help getting it across the finish line. Thank you.

# Conflicts:
#	python/packages/core/agent_framework/_workflows/_checkpoint_encoding.py
@moonbox3
Evan Mattson (moonbox3) added this pull request to the merge queue Jul 30, 2026
Merged via the queue into microsoft:main with commit 143386f Jul 30, 2026
37 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

python Usage: [Issues, PRs], Target: Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python: Restrict checkpoint unpickler globals and attribute traversal

4 participants