Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,17 @@ dependencies = [
"griffelib>=2, <3",
"typing-extensions>=4.12.2, <5",
"requests>=2.0, <3",
# urllib3 is pulled in transitively via requests; pin a safe floor so
# installs cannot resolve to a version exposed to the disclosed CVEs
# (highest fix 2.7.0, GHSA-qccp-gfcp-xxvc cross-origin header leak).
"urllib3>=2.7.0, <3",
"websockets>=15.0, <17",
"mcp>=1.19.0, <3; python_version >= '3.10'",
# cryptography enters the base graph transitively via mcp -> pyjwt[crypto],
# whose own requirement is unpinned; pin a safe floor so a base install
# cannot retain a version exposed to the disclosed CVE (46.0.7 fixes the
# 9.8-critical GHSA-p423-j2cm-9vmq buffer overflow).
"cryptography>=46.0.7, <47",
]
classifiers = [
"Typing :: Typed",
Expand All @@ -40,14 +49,14 @@ litellm = ["litellm>=1.83.0"]
any-llm = ["any-llm-sdk>=1.11.0, <2; python_version >= '3.11'"]
realtime = ["websockets>=15.0, <17"]
sqlalchemy = ["SQLAlchemy>=2.0", "asyncpg>=0.29.0"]
encrypt = ["cryptography>=45.0, <46"]
encrypt = ["cryptography>=46.0.7, <47"]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Apply the cryptography floor to base installs

When a user upgrades the base openai-agents package without the encrypt extra in an environment containing vulnerable cryptography 45.x, this constraint is never evaluated. The base dependency graph already installs cryptography through mcpPyJWT[crypto], whose looser requirement allows pip to retain 45.x; the lockfile upgrade therefore does not remediate those published installations. Add the safe cryptography>=46.0.7,<47 constraint to the core dependencies (or otherwise constrain the base graph), as was done for transitive urllib3.

AGENTS.md reference: AGENTS.md:L145-L147

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Good catch, fixed in 7c54392. Confirmed the transitive path: base dep mcp>=1.19.0 requires pyjwt[crypto], which pulls cryptography into the base graph with no floor of its own, so a base openai-agents upgrade (without the encrypt extra) could retain vulnerable 45.x. Added cryptography>=46.0.7,<47 to the core dependencies (unmarked; the package is requires-python >= 3.10) plus the matching base requires-dist entry in uv.lock, mirroring the urllib3 base-floor already applied for the requests-transitive CVEs. Resolution graph is unchanged (already resolved to 46.0.7).

redis = ["redis>=7"]
dapr = ["dapr>=1.16.0", "grpcio>=1.60.0"]
mongodb = ["pymongo>=4.14"]
docker = ["docker>=6.1"]
blaxel = ["blaxel>=0.2.50", "aiohttp>=3.12,<4"]
blaxel = ["blaxel>=0.2.50", "aiohttp>=3.14.3,<4"]
daytona = ["daytona>=0.155.0"]
cloudflare = ["aiohttp>=3.12,<4"]
cloudflare = ["aiohttp>=3.14.3,<4"]
e2b = ["e2b==2.31.0", "e2b-code-interpreter==2.8.1"]
modal = ["modal==1.4.3"]
runloop = ["runloop_api_client>=1.16.0,<2.0.0"]
Expand Down Expand Up @@ -84,7 +93,7 @@ dev = [
"eval-type-backport>=0.2.2",
"fastapi >= 0.110.0, <1",
"aiosqlite>=0.21.0",
"cryptography>=45.0, <46",
"cryptography>=46.0.7, <47",
"fakeredis>=2.31.3",
"dapr>=1.14.0",
"grpcio>=1.60.0",
Expand Down
6 changes: 3 additions & 3 deletions src/agents/extensions/sandbox/cloudflare/sandbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ def _sanitize_persisted_provider_identity(
class _CloudflarePtyProcessEntry:
"""Per-process state for a Cloudflare WebSocket PTY session."""

ws: aiohttp.ClientWebSocketResponse
ws: aiohttp.ClientWebSocketResponse[bool]
tty: bool
last_used: float = field(default_factory=time.monotonic)
output_chunks: deque[bytes] = field(default_factory=deque)
Expand Down Expand Up @@ -1114,7 +1114,7 @@ async def _terminate_pty_entry(self, entry: _CloudflarePtyProcessEntry) -> None:
async def _cleanup_unregistered_pty(
self,
entry: _CloudflarePtyProcessEntry | None,
ws: aiohttp.ClientWebSocketResponse | None,
ws: aiohttp.ClientWebSocketResponse[bool] | None,
registered: bool,
) -> None:
"""Best-effort cleanup of a PTY WebSocket or entry that was never registered."""
Expand All @@ -1138,7 +1138,7 @@ async def pty_exec_start(
sanitized_command = self._prepare_exec_command(*command, shell=shell, user=user)
command_text = shlex.join(str(part) for part in sanitized_command)

ws: aiohttp.ClientWebSocketResponse | None = None
ws: aiohttp.ClientWebSocketResponse[bool] | None = None
entry: _CloudflarePtyProcessEntry | None = None
registered = False
pruned_entry: _CloudflarePtyProcessEntry | None = None
Expand Down
Loading