Skip to content

Commit a547be1

Browse files
committed
fix: CI pip install failure + 2 bandit security issues
- Remove pysqlite3 from [dev] deps (caused pip resolution failure on CI; keep in [graphqlite] where it belongs; code already handles import error) - Fix B324: add usedforsecurity=False to hashlib.md5() call - Fix B202: add safe member validation to tarfile.extractall() (use filter='data' on Python 3.12+, manual validation on older)
1 parent 34d5504 commit a547be1

3 files changed

Lines changed: 22 additions & 6 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,7 @@ github = [
9696
"PyGithub>=2.0.0",
9797
]
9898
dev = [
99-
"graphqlite>=0.6.0",
100-
"pysqlite3>=0.6.0",
99+
"teaagent[graphqlite]",
101100
"teaagent[crypto]",
102101
"watchdog>=3.0.0",
103102
"prompt-toolkit>=3.0.0",

teaagent/subagents/_feature_flags.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,9 @@ def should_use_hybrid_queue(self, request_id: str) -> bool:
183183
# Use consistent hashing based on request_id
184184
import hashlib
185185

186-
hash_value = int(hashlib.md5(request_id.encode()).hexdigest(), 16)
186+
hash_value = int(
187+
hashlib.md5(request_id.encode(), usedforsecurity=False).hexdigest(), 16
188+
)
187189
threshold = (rollout_percentage / 100) * (2**32)
188190
return hash_value % (2**32) < threshold
189191

teaagent/update/installer.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
import hashlib
1212
import json
1313
import shutil
14+
import sys
15+
import tarfile
1416
import tempfile
1517
from dataclasses import dataclass, field
1618
from enum import Enum
@@ -160,6 +162,18 @@ def verify_checksum(self, file_path: Path, expected_checksum: str) -> bool:
160162
return sha256_hash.hexdigest() == expected_checksum
161163

162164

165+
def _safe_extract(tar: tarfile.TarFile, path: Path) -> None:
166+
"""Extract tar safely, preventing path traversal."""
167+
for member in tar.getmembers():
168+
member_path = (path.resolve() / member.name).resolve()
169+
if not str(member_path).startswith(str(path.resolve())):
170+
raise tarfile.ExtractError(
171+
f'Unsafe tar member: {member.name} would escape {path}'
172+
)
173+
# bandit B202: members validated above — safe to extract
174+
tar.extractall(path) # nosec
175+
176+
163177
class UpdateInstaller:
164178
"""Installer for update packages."""
165179

@@ -221,10 +235,11 @@ def install_package(
221235

222236
try:
223237
# Extract package (placeholder - assumes tar.gz)
224-
import tarfile
225-
226238
with tarfile.open(package_path, 'r:gz') as tar:
227-
tar.extractall(self.install_dir)
239+
if sys.version_info >= (3, 12):
240+
tar.extractall(self.install_dir, filter='data')
241+
else:
242+
_safe_extract(tar, self.install_dir)
228243

229244
if progress_callback:
230245
progress_callback(75)

0 commit comments

Comments
 (0)