diff --git a/CHANGELOG.md b/CHANGELOG.md index 66eafdb3a..ebcfbe3f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Security + +- Require GitPython 3.2.0 or newer in the `mlflow`, `all-ci`, and `all` extras and lockfile to fix `Remote.pull()` refspec option injection ([GHSA-f9j4-qggq-h239](https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-f9j4-qggq-h239)). +- Require AnyIO 4.14.2 or newer in published package dependencies as well as the lockfile. + ### Changed - Include original credential values and configured debug paths in scan evidence, diagnostics, and exported reports while retaining detections and output bounds. diff --git a/pyproject.toml b/pyproject.toml index da311c0f0..a8c950859 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,6 +42,7 @@ dependencies = [ "defusedxml>=0.7.1", "huggingface-hub>=0.23.0", "requests>=2.28.0", + "anyio>=4.14.2", "python-dotenv>=1.0.0", "platformdirs>=3.0.0", "pyyaml>=6.0,<7.0", @@ -83,6 +84,7 @@ xgboost = [ ] mlflow = [ "mlflow-skinny>=3.13.0", + "gitpython>=3.2.0", "sqlalchemy>=2.0.49", "alembic>=1.18.4", "sqlparse>=0.6.0", @@ -128,6 +130,7 @@ all-ci = [ "py-ubjson>=0.16.0", "py7zr>=1.1.3", "mlflow-skinny>=3.13.0", + "gitpython>=3.2.0", "sqlalchemy>=2.0.49", "alembic>=1.18.4", "sqlparse>=0.6.0", @@ -159,6 +162,7 @@ all = [ "py-ubjson>=0.16.0", "py7zr>=1.1.3", "mlflow-skinny>=3.13.0", + "gitpython>=3.2.0", "sqlalchemy>=2.0.49", "alembic>=1.18.4", "sqlparse>=0.6.0", diff --git a/tests/test_dependency_lock.py b/tests/test_dependency_lock.py index 00d19ddfb..c719b2955 100644 --- a/tests/test_dependency_lock.py +++ b/tests/test_dependency_lock.py @@ -18,8 +18,10 @@ ROOT_PYPROJECT = ROOT_DIR / "pyproject.toml" RENOVATE_CONFIG = ROOT_DIR / "renovate.json" PICKLESCAN_PYPROJECT = ROOT_DIR / "packages" / "modelaudit-picklescan" / "pyproject.toml" -PATCHED_GITPYTHON_FLOOR = (3, 1, 60) +PATCHED_GITPYTHON_FLOOR = (3, 2, 0) PATCHED_ANYIO_FLOOR = (4, 14, 2) +PATCHED_GITPYTHON_REQUIREMENT = "gitpython>=3.2.0" +PATCHED_ANYIO_REQUIREMENT = "anyio>=4.14.2" PINNED_MATURIN_BACKEND = "maturin===1.13.3" PATCHED_PY7ZR_REQUIREMENT = "py7zr>=1.1.3" PY7ZR_EXTRAS = ("sevenzip", "all-ci", "all") @@ -109,6 +111,13 @@ def test_mlflow_extras_use_the_hardened_tracking_client() -> None: for extra in MLFLOW_EXTRAS: assert PATCHED_MLFLOW_CLIENT_REQUIREMENT in optional_dependencies[extra] + assert PATCHED_GITPYTHON_REQUIREMENT in optional_dependencies[extra] + + +def test_base_install_requires_patched_anyio() -> None: + root_config = tomllib.loads(ROOT_PYPROJECT.read_text(encoding="utf-8")) + + assert PATCHED_ANYIO_REQUIREMENT in root_config["project"]["dependencies"] @pytest.mark.parametrize("extra", MLFLOW_EXTRAS) diff --git a/uv.lock b/uv.lock index eb6980dcd..18fb0275b 100644 --- a/uv.lock +++ b/uv.lock @@ -1140,14 +1140,14 @@ wheels = [ [[package]] name = "gitpython" -version = "3.1.62" +version = "3.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "gitdb" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e0/db/3ca813cbacb23ab6fe46ff38a9b5ef8e73e970c8051f2ce903aacafe0446/gitpython-3.1.62.tar.gz", hash = "sha256:1791de66309bc0c7cfca40bf8d2e3de7ca091cbf94e6051be1ad0722c61062af", size = 231728, upload-time = "2026-09-07T02:57:21.155Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6e/2d/6f6e649818da44d4499604802c89329b8d9799687a124e3a5e467a643336/gitpython-3.2.0.tar.gz", hash = "sha256:fb92310af6844d96adc95ca066ed2e617c00e1dbd146a326626c81e72e18cc2e", size = 238091, upload-time = "2026-09-30T09:10:32.65Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d6/0b/29d7965215f8ef830a7ca1f42997fe13e5693d85e9edb18f938d063ef5f2/gitpython-3.1.62-py3-none-any.whl", hash = "sha256:7002251225e10e29d2e1f49e6532613fe5d5d9f0b6f1f02997a52b38fe56899e", size = 222753, upload-time = "2026-09-07T02:57:19.762Z" }, + { url = "https://files.pythonhosted.org/packages/fa/48/f36d233ce749d1bb880cb5e6f8bb171dc2effabc7435c31da604d831b3ec/gitpython-3.2.0-py3-none-any.whl", hash = "sha256:bd70c5ec05cd2b797423e7eb312147d2458d3cca92085888fba2213f85905537", size = 228537, upload-time = "2026-09-30T09:10:31.159Z" }, ] [[package]] @@ -1985,6 +1985,7 @@ name = "modelaudit" version = "0.2.53" source = { editable = "." } dependencies = [ + { name = "anyio" }, { name = "click" }, { name = "cyclonedx-python-lib" }, { name = "defusedxml" }, @@ -2015,6 +2016,7 @@ dependencies = [ all = [ { name = "alembic" }, { name = "dill" }, + { name = "gitpython" }, { name = "h5py" }, { name = "huggingface-hub" }, { name = "joblib" }, @@ -2038,6 +2040,7 @@ all = [ all-ci = [ { name = "alembic" }, { name = "dill" }, + { name = "gitpython" }, { name = "h5py" }, { name = "huggingface-hub" }, { name = "joblib" }, @@ -2080,6 +2083,7 @@ joblib = [ ] mlflow = [ { name = "alembic" }, + { name = "gitpython" }, { name = "mlflow-skinny" }, { name = "sqlalchemy", version = "2.0.54", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, { name = "sqlalchemy", version = "2.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, @@ -2152,6 +2156,7 @@ requires-dist = [ { name = "alembic", marker = "extra == 'all'", specifier = ">=1.18.4" }, { name = "alembic", marker = "extra == 'all-ci'", specifier = ">=1.18.4" }, { name = "alembic", marker = "extra == 'mlflow'", specifier = ">=1.18.4" }, + { name = "anyio", specifier = ">=4.14.2" }, { name = "click", specifier = ">=8.3.3" }, { name = "cyclonedx-python-lib", specifier = ">=11.0.0" }, { name = "defusedxml", specifier = ">=0.7.1" }, @@ -2162,6 +2167,9 @@ requires-dist = [ { name = "dill", marker = "extra == 'numpy1'", specifier = ">=0.3.0,<1.0" }, { name = "fsspec", specifier = ">=2025.5.1" }, { name = "gcsfs", specifier = ">=2025.5.1" }, + { name = "gitpython", marker = "extra == 'all'", specifier = ">=3.2.0" }, + { name = "gitpython", marker = "extra == 'all-ci'", specifier = ">=3.2.0" }, + { name = "gitpython", marker = "extra == 'mlflow'", specifier = ">=3.2.0" }, { name = "h5py", marker = "extra == 'all'", specifier = ">=3.1,<4.0" }, { name = "h5py", marker = "extra == 'all-ci'", specifier = ">=3.1,<4.0" }, { name = "h5py", marker = "extra == 'h5'", specifier = ">=3.1,<4.0" },