mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-08-29 02:26:59 +08:00
6b07f5492f
Updates the pinned FastAPI/Starlette versions on release_25.1 to match
upstream/dev, closing CVE-2026-48710 ("BadHost"). The vulnerability lets
an attacker inject a path into the HTTP Host header and have
``request.url.path`` reflect that path, bypassing path-based access
control in middleware. Starlette 1.0.1+ rejects Host headers with
invalid characters; we pin starlette==1.1.0 to match dev.
Drops Python 3.9 support, matching upstream/dev (commit eb9fde1dcd).
Starlette dropped 3.9 in 0.50.0, so the BadHost fix (starlette >= 1.0.1)
cannot be installed on 3.9. Bumping the floor to 3.10 is the only way
to ship the security fix; the alternative -- marker-splitting the pins
to keep 3.9 on starlette 0.49.x -- would leave 3.9 users exposed to the
CVE we are trying to close.
Actual exposure on release_25.1 (pre-fix)
-----------------------------------------
Galaxy was running a vulnerable starlette but is **not exploitable for
the headline auth-bypass scenario**. Auth runs through FastAPI
dependencies (``get_user``, ``get_trans``, ``AdminUserRequired``), not
through path-string checks in middleware. ``AccessLoggingMiddleware``
already uses ``scope["path"]``; ``add_galaxy_middleware`` /
``GalaxyCORSMiddleware`` / ``RawContextMiddleware`` /
``SentryAsgiMiddleware`` do not branch on ``request.url.path``.
Lower-severity findings that this upgrade also closes:
- ``lib/galaxy/webapps/base/api.py`` ``get_error_response_for_request``
picks an error schema with ``"ga4gh"/"drs"/"trs" in
request.url.path`` -- spoofable Host nudges error payload shape
(info-disclosure / shape confusion only).
- ``lib/galaxy/webapps/galaxy/api/drs.py`` and
``lib/galaxy/webapps/galaxy/services/datasets.py`` derive DRS
``service_info`` / ``self_uri`` from ``request.url`` -- spoofable
Host poisons the advertised DRS identity and client-visible URIs,
not access.
- ``lib/tool_shed/webapp/api2/tools.py`` -- same shape, TRS service
info.
Bumping the pin closes the parser flaw at source and downgrades all of
the above to non-issues, so no separate ``request.url.path ->
scope["path"]`` sweep is needed.
Pin bumps (cherry-picks the relevant ranges from PRs #21526, #22206,
#22754):
- fastapi 0.118.0 -> 0.136.3
- starlette 0.48.0 -> 1.1.0
- starlette-context 0.4.0 -> 0.5.1
- python-multipart 0.0.20 -> 0.0.29
- anyio 4.11.0 -> 4.13.0
Required code changes backported from upstream/dev:
- ``lib/galaxy/webapps/openapi/_compat/v2.py``: import
``GenerateJsonSchema`` and ``get_flat_models_from_fields`` from
``fastapi._compat.v2`` and adopt the new ``get_definitions()``
implementation for FastAPI 0.128.8+ (PRs #21384, dev commits
0800c025ce, c8ccc7f44d, b3bfb45884).
- ``lib/galaxy/webapps/openapi/utils.py``: route ``GenerateJsonSchema``
through ``_compat.v2`` and drop the now-unreachable
``get_compat_model_name_map`` fallback (dev commit b3bfb45884).
- ``lib/galaxy/schema/generics.py``: drop ``CustomJsonSchema`` here
(moved to fast_app.py so it can use the patched ``GenerateJsonSchema``
from ``_compat.v2``).
- ``lib/galaxy/webapps/galaxy/fast_app.py``: relocate
``CustomJsonSchema`` and switch its base to the ``_compat.v2``
``GenerateJsonSchema``; replace the @app.middleware("http") X-Frame
Options handler with a pure ASGI ``XFrameOptionsMiddleware`` class
(dev commit 67eea395ab) since ``BaseHTTPMiddleware`` semantics
changed in starlette 1.0.
- ``lib/galaxy/webapps/base/api.py`` and
``lib/galaxy/webapps/galaxy/api/datasets.py``: drop the ``method``
argument of ``FileResponse`` which starlette 1.0 removed (dev commit
63954cb42e).
Also bumps the minimum FastAPI requirement to ``>=0.133.0`` (first
version compatible with starlette>=1.0.0) and adds an explicit
``starlette>=1.0.1`` floor in ``pyproject.toml`` and the
``packages/web_apps`` / ``packages/tool_shed`` setup.cfg files so
source installs cannot resolve to a vulnerable combo.
Co-authored-by: Nicola Soranzo <nicola.soranzo@gmail.com>
266 lines
8.5 KiB
TOML
266 lines
8.5 KiB
TOML
[project]
|
|
name = "galaxy"
|
|
version = "0.1.0" # Not the real version, which is instead defined in lib/galaxy/version.py
|
|
description = "Galaxy is an open, web-based platform for accessible, reproducible, and transparent computational research."
|
|
authors = [
|
|
{name = "Galaxy Contributors"},
|
|
]
|
|
maintainers = [
|
|
{name = "Galaxy Committers", email = "galaxy-committers@lists.galaxyproject.org"}
|
|
]
|
|
license = {file = "LICENSE.txt"}
|
|
readme = "README.rst"
|
|
requires-python = ">=3.10"
|
|
dependencies = [
|
|
"a2wsgi",
|
|
"aiofiles",
|
|
"alembic",
|
|
"apispec",
|
|
"Babel",
|
|
"bdbag>=1.6.3",
|
|
"Beaker",
|
|
"bioblend",
|
|
"bleach",
|
|
"boltons",
|
|
"boto",
|
|
"bx-python",
|
|
"celery>=5.4.0", # prefer not downgrading this to upgrading typing-extensions
|
|
"cloudauthz==0.6.0",
|
|
"cloudbridge",
|
|
"circus",
|
|
"conda-package-streaming",
|
|
"CT3>=3.3.3", # Python 3.13 support
|
|
"cwl-utils>=0.13",
|
|
"cwltool>=3.1.20230624081518", # save time, minimum needed by cwl-1.0 branch
|
|
"dictobj",
|
|
"dnspython",
|
|
"docutils!=0.17,!=0.17.1",
|
|
"dparse",
|
|
"edam-ontology",
|
|
"fastapi>=0.133.0", # First version compatible with starlette>=1.0.0
|
|
"fissix",
|
|
"fs",
|
|
"future>=1.0.0", # Python 3.12 support
|
|
"gravity>=1.1.1",
|
|
"gunicorn",
|
|
"gxformat2>=0.21.0",
|
|
"h5grove>=1.2.1",
|
|
"h5py>=3.12", # Python 3.13 support
|
|
"httpx",
|
|
"ijson",
|
|
"importlib-resources ; python_version<'3.12'", # for importlib.{abc.Traversable,resources.{files, Package}}
|
|
"isa-rwval>=0.10.11", # https://github.com/ISA-tools/isa-rwval/pull/17
|
|
"isal>=1.7.0", # Python 3.13 support
|
|
"jinja2",
|
|
"kombu>=5.5.0", # prefer not downgrading this to upgrading typing-extensions
|
|
"lagom",
|
|
"Mako",
|
|
"Markdown",
|
|
"MarkupSafe",
|
|
"mercurial>=6.8.2", # Python 3.13 support
|
|
"mrcfile",
|
|
"more-itertools",
|
|
"msal",
|
|
"nodejs-wheel>=22,<23",
|
|
"numpy>=1.26.0", # Python 3.12 support
|
|
"numpy>=2.1.0 ; python_version>='3.10'", # Python 3.13 support
|
|
"openpyxl>=3.1.5", # Minimum version ever tested with
|
|
"packaging",
|
|
"paramiko!=2.9.0,!=2.9.1", # https://github.com/paramiko/paramiko/issues/1961
|
|
"Parsley",
|
|
"Paste",
|
|
"pebble",
|
|
"pillow",
|
|
"psutil",
|
|
"pulsar-galaxy-lib>=0.15.10",
|
|
"pycryptodome",
|
|
"pydantic[email]>=2.7.4", # https://github.com/pydantic/pydantic/pull/9639
|
|
"PyJWT",
|
|
"pykwalify",
|
|
"pylibmagic",
|
|
"pyparsing",
|
|
"pypng",
|
|
"pysam>=0.21", # for Python 3.11 support on macOS
|
|
"python-dateutil",
|
|
"python-magic",
|
|
"python-multipart", # required to support form parsing in FastAPI/Starlette
|
|
"python-slugify",
|
|
"PyYAML",
|
|
"refgenconf>=0.12.0",
|
|
"regex",
|
|
"requests",
|
|
"rocrate",
|
|
"Routes",
|
|
"s3fs>=2023.1.0",
|
|
"schema-salad>=8.7.20240905150001", # Python 3.13 support
|
|
"slowapi",
|
|
"social-auth-core>=4.5.0", # to drop dependency on abandoned python-jose
|
|
"sortedcontainers",
|
|
"SQLAlchemy>=2.0.37,<2.1,!=2.0.41", # https://github.com/sqlalchemy/sqlalchemy/issues/12019 , https://github.com/sqlalchemy/sqlalchemy/issues/12600
|
|
"sqlparse",
|
|
"starlette>=1.0.1", # CVE-2026-48710 BadHost
|
|
"starlette-context",
|
|
"svgwrite",
|
|
"tifffile",
|
|
"tuswsgi",
|
|
"typing-extensions",
|
|
"uvicorn!=0.28.0", # https://github.com/galaxyproject/galaxy/issues/17669
|
|
"uvloop>=0.21.0", # Python 3.13 support
|
|
"WebOb>=1.8.9", # Python 3.13 support
|
|
"Whoosh",
|
|
"zipstream-new",
|
|
"fsspec>=2025.7.0",
|
|
]
|
|
|
|
[project.urls]
|
|
Homepage = "https://galaxyproject.org/"
|
|
Documentation = "https://docs.galaxyproject.org/"
|
|
Repository = "https://github.com/galaxyproject/galaxy"
|
|
"Bug Tracker" = "https://github.com/galaxyproject/galaxy/issues"
|
|
|
|
[dependency-groups]
|
|
test = [
|
|
"ase>=3.18.1",
|
|
"axe-selenium-python",
|
|
"boto3",
|
|
"cwltest>=2.5.20240906231108", # Python 3.13 support
|
|
"fluent-logger",
|
|
"lxml!=4.2.2",
|
|
"onedatafilerestclient==21.2.5.2",
|
|
"pkce",
|
|
"playwright>=1.48.0", # Python 3.13 support
|
|
"pytest",
|
|
"pytest-asyncio",
|
|
"pytest-cov",
|
|
"pytest-html",
|
|
"pytest-httpserver",
|
|
"python-irodsclient!=1.1.2", # https://github.com/irods/python-irodsclient/issues/356
|
|
"pytest-json-report",
|
|
"pytest-mock",
|
|
"pytest-playwright",
|
|
"pytest-postgresql!=3.0.0", # https://github.com/ClearcodeHQ/pytest-postgresql/issues/426
|
|
"pytest-shard",
|
|
"responses",
|
|
"roc-validator!=0.7.2", # https://github.com/crs4/rocrate-validator/pull/97
|
|
"rucio-clients>=37.2.0", # https://github.com/rucio/rucio/pull/7665
|
|
"selenium",
|
|
"seletools",
|
|
"statsd",
|
|
"testfixtures",
|
|
"total-perspective-vortex>=3.1.1,<4", # https://github.com/galaxyproject/total-perspective-vortex/pull/173
|
|
"tuspy",
|
|
"twill>=3.2.5", # Python 3.13 support
|
|
"watchdog",
|
|
"Werkzeug",
|
|
]
|
|
dev = [
|
|
{include-group = "test"},
|
|
"black",
|
|
"codespell",
|
|
"darker",
|
|
"galaxy-release-util",
|
|
"isort",
|
|
"markdown-it-reporter",
|
|
"myst-parser",
|
|
"Sphinx>=4.0", # support docutils 0.17
|
|
"sphinx-rtd-theme",
|
|
]
|
|
typecheck = [
|
|
"boto3-stubs[s3]",
|
|
"lxml-stubs",
|
|
"mypy",
|
|
"pydantic>=2.7.4", # for pydantic.mypy plugin
|
|
"types-bleach",
|
|
"types-boto",
|
|
"types-contextvars",
|
|
"types-dataclasses",
|
|
"types-docutils",
|
|
"types-Markdown",
|
|
"types-paramiko",
|
|
"types-python-dateutil",
|
|
"types-python-slugify",
|
|
"types-PyYAML",
|
|
"types-requests",
|
|
"types-setuptools",
|
|
"types-six",
|
|
]
|
|
|
|
[tool.black]
|
|
line-length = 120
|
|
include = '\.pyi?$'
|
|
extend-exclude = '''
|
|
^/(
|
|
| packages
|
|
| lib/tool_shed/test/test_data/repos
|
|
)/
|
|
'''
|
|
|
|
[tool.darker]
|
|
isort = true
|
|
|
|
[tool.ruff]
|
|
exclude = [
|
|
"lib/tool_shed/test/test_data/repos"
|
|
]
|
|
|
|
[tool.ruff.lint]
|
|
# Enable: pycodestyle errors (E), Pyflakes (F), flake8-bugbear (B),
|
|
# flake8-comprehensions (C4), flake8-logging-format (G),
|
|
# flake8-implicit-str-concat (ISC) and pyupgrade (UP)
|
|
select = ["E", "F", "B", "C4", "G", "ISC", "NPY", "UP"]
|
|
# Exceptions:
|
|
# B008 Do not perform function calls in argument defaults (for FastAPI Depends and Body)
|
|
# B9 flake8-bugbear opinionated warnings
|
|
# E402 module level import not at top of file # TODO, we would like to improve this.
|
|
# E501 is line length (delegated to black)
|
|
# G* are TODOs
|
|
# UP006 and UP035 are PEP 585 type annotations
|
|
# UP006, UP007, UP035, UP036, UP041, UP045: Python >=3.10 improvements;
|
|
# keep the code 3.9-syntax-compatible for now, to be revisited later.
|
|
ignore = ["B008", "B9", "E402", "E501", "G001", "G002", "G004", "UP006", "UP007", "UP035", "UP036", "UP041", "UP045"]
|
|
|
|
[tool.ruff.lint.flake8-comprehensions]
|
|
allow-dict-calls-with-keyword-arguments = true
|
|
|
|
[tool.ruff.lint.isort]
|
|
# We are not selecting "I" rules in ruff yet because support for all the isort
|
|
# options we need is not complete, but these are the one currently implemented.
|
|
combine-as-imports = true
|
|
relative-imports-order = "closest-to-furthest"
|
|
|
|
[tool.ruff.lint.pyupgrade]
|
|
# Preserve types, even if a file imports `from __future__ import annotations`.
|
|
keep-runtime-typing = true
|
|
|
|
[tool.ruff.lint.per-file-ignores]
|
|
# Don't check pyupgrade rules on tool scripts, which may use different Python versions
|
|
"test/functional/tools/*" = ["UP"]
|
|
"tools/*" = ["UP"]
|
|
# Don't check pyupgrade rules on generated files
|
|
"lib/galaxy/schema/bco/*" = ["UP"]
|
|
"lib/galaxy/schema/drs/*" = ["UP"]
|
|
"lib/tool_shed_client/schema/trs.py" = ["UP"]
|
|
"lib/tool_shed_client/schema/trs_service_info.py" = ["UP"]
|
|
# Don't check some pyupgrade rules on packages for Pulsar, which need to stay compatible with Python 3.7
|
|
"lib/galaxy/exceptions/*" = ["UP006", "UP007", "UP033", "UP035", "UP036"]
|
|
"lib/galaxy/job_metrics/*" = ["UP006", "UP007", "UP033", "UP035", "UP036"]
|
|
"lib/galaxy/objectstore/*" = ["UP006", "UP007", "UP033", "UP035", "UP036"]
|
|
"lib/galaxy/tool_util/*" = ["UP006", "UP007", "UP033", "UP035", "UP036"]
|
|
"lib/galaxy/util/*" = ["UP006", "UP007", "UP033", "UP035", "UP036"]
|
|
"scripts/check_python.py" = ["UP006", "UP007", "UP010", "UP032", "UP033", "UP035", "UP036"]
|
|
"test/unit/job_metrics/*" = ["UP006", "UP007", "UP033", "UP035", "UP036"]
|
|
"test/unit/objectstore/*" = ["UP006", "UP007", "UP033", "UP035", "UP036"]
|
|
"test/unit/tool_util/*" = ["UP006", "UP007", "UP033", "UP035", "UP036"]
|
|
"test/unit/util/*" = ["UP006", "UP007", "UP033", "UP035", "UP036"]
|
|
|
|
[tool.uv]
|
|
constraint-dependencies = [
|
|
"limits>=2.5.0", # prefer not downgrading this to upgrading packaging
|
|
"setuptools<82", # https://github.com/PyFilesystem/pyfilesystem2/issues/597
|
|
"scipy>=1.14.1; python_version>='3.10'", # Python 3.13 support
|
|
]
|
|
default-groups = []
|
|
extra-index-url = ["https://wheels.galaxyproject.org/simple"]
|
|
index-strategy = "unsafe-best-match"
|
|
package = false
|