Skip to content

The transformers>=5.3.0 floor (described as a CVE fix floor) admits CVE-2026-5241 and CVE-2026-9856, and both reach ForgeLM's own load and save path from a Hub repo (CR-A16-009) #109

Open

Description

@cemililik

Wave 0 · theme D0-7: Dependency ranges and security floors · highest severity High · 3 finding(s) · effort small

Summary

pyproject.toml:53 declares transformers>=5.3.0,<6.0.0. The nightly floor job's comment calls 5.3.0 'the CVE-2026-4372 fix floor' (.github/workflows/nightly.yml:239-241, pinned at :246). The tools/pip_audit_ignores.yaml:37-42 comment presents the floor as having cleared the transformers advisories. PyPI's vulnerability data for transformers 5.3.0, fetched 2026-10-08, still lists three high advisories: - GHSA-fgcw-684q-jj6r / CVE-2026-5241: a LightGlue config.json overrides trust_remote_code. Fixed in 5.5.0. - GHSA-xrqw-3rrv-vx5w / CVE-2026-9856 / PYSEC-2026-3929: chat_template names in tokenizer_config.json are used unsanitised as filenames by save_pretrained. Fixed in 5.10.0. - GHSA-x9r9-c232-4q39 / CVE-2026-80047: affects >=4.49.0,<=5.8.1, with no fix listed. I reproduced the first two through ForgeLM's own code, offline, with the tiny fixture: (a) CVE-2026-9856: forgelm.model._load_tokenizer (forgelm/model.py:390-393) loaded a crafted copy of tiny-qwen whose chat_template list contains the name '../../../ESCAPED_BY_CHAT_TEMPLATE'. tokenizer.save_pretrained(/final_model) then ran, as ForgeTrainer.save_final_model does (forgelm/trainer.py:1730, :1749; also export.py:184 and m…

Primary finding

CR-A16-009 — The transformers>=5.3.0 floor (described as a CVE fix floor) admits CVE-2026-5241 and CVE-2026-9856, and both reach ForgeLM's own load and save path from a Hub repo

severity High · reachability default · intent contract-violation · confidence confirmed · independently confirmed · reproduced end to end

What happens. pyproject.toml:53 declares transformers>=5.3.0,<6.0.0. The nightly floor job's comment calls 5.3.0 'the CVE-2026-4372 fix floor' (.github/workflows/nightly.yml:239-241, pinned at :246). The tools/pip_audit_ignores.yaml:37-42 comment presents the floor as having cleared the transformers advisories. PyPI's vulnerability data for transformers 5.3.0, fetched 2026-10-08, still lists three high advisories: - GHSA-fgcw-684q-jj6r / CVE-2026-5241: a LightGlue config.json overrides trust_remote_code. Fixed in 5.5.0. - GHSA-xrqw-3rrv-vx5w / CVE-2026-9856 / PYSEC-2026-3929: chat_template names in tokenizer_config.json are used unsanitised as filenames by save_pretrained. Fixed in 5.10.0. - GHSA-x9r9-c232-4q39 / CVE-2026-80047: affects >=4.49.0,<=5.8.1, with no fix listed. I reproduced the first two through ForgeLM's own code, offline, with the tiny fixture: (a) CVE-2026-9856: forgelm.model._load_tokenizer (forgelm/model.py:390-393) loaded a crafted copy of tiny-qwen whose chat_template list contains the name '../../../ESCAPED_BY_CHAT_TEMPLATE'. tokenizer.save_pretrained(/final_model) then ran, as ForgeTrainer.save_final_model does (forgelm/trainer.py:1730, :1749; also export.py:184 and merging.py:100). On 5.3.0 this wrote run/ESCAPED_BY_CHAT_TEMPLATE.jinja with attacker content outside final_model. On 5.13.0 and 5.18.0, loading raises ValueError 'Invalid chat template name'. (b) CVE-2026-5241: forgelm.model.get_model_and_tokenizer ran with ForgeConfig model.trust_remote_code: false on a repo whose config.json has model_type 'lightglue', trust_remote_code: true and a keypoint_detector_config._name_or_path pointing at a repo with an auto_map configuration module. On 5.3.0 that module executed: the marker file was written before ForgeLM's tokenizer error. On 5.13.0 and 5.18.0 it…

Where.

Evidence.

  • Lower venv transformers 5.3.0: chat_tpl_traversal.py printed "files named ESCAPED*: ['run/ESCAPED_BY_CHAT_TEMPLATE.jinja']" with nothing inside final_model; lightglue_trc.py printed "config.model.trust_remote_code = False" and "REMOTE CODE EXECUTED: True". Extras venv 5.13.0 and latest venv 5.18.0: 'RAISED ValueError Invalid chat template name' and 'REMOTE CODE EXECUTED: False'. PyPI https://pypi.org/pypi/transformers/5.3.0/json vulnerabilities: GHSA-fgcw-684q-jj6r fixed_in 5.5.0; GHSA-xrqw-3rr…

Recommended fix. Raise the floor to transformers>=5.10.0. T02 reports 5.10.0 as yanked, so pip would pick 5.10.1. I did not re-check that. Move the nightly floor pin with it, drop the 'CVE fix floor' framing or keep it accurate, and add a regression test that a traversal chat_template name cannot escape the save directory. Land this together with the top-of-range fixes (M-X-011).

Other findings with the same root cause

These close with the same fix; update them in the same pull request.

TECH-T02-002 — Core Hugging Face stack and runtime dependencies: transformers>=5.3.0,<6.0.0 (pyproject.toml:53): version range and the CVE-2026-4372 floor (range-unsound)

severity Now

Item. transformers>=5.3.0,<6.0.0 (pyproject.toml:53): version range and the CVE-2026-4372 floor · verdict: range-unsound · urgency: Now

State in ForgeLM. pyproject.toml:53 declares transformers>=5.3.0,<6.0.0. CHANGELOG.md:1561 and docs/roadmap/releases.md:394,405 record 5.3.0 as the CVE-2026-4372 fix floor. tools/pip_audit_ignores.yaml:36-42 suppresses no transformers advisory. The venvs hold lower 5.3.0, project 5.13.0 and latest 5.18.0.

State of the ecosystem on 2026-10-01. Latest stable is 5.18.0 (2026-09-30), inside <6. CVE-2026-4372 is real: NVD lists it as Analyzed (published 2026-05-24), and GHSA-29pf-2h5f-8g72 gives 5.3.0 as first patched. Three newer advisories still affect the floor: - CVE-2026-5241 (GHSA-fgcw-684q-jj6r): a LightGlue config.json overrides trust_remote_code. Affects <5.5.0. - CVE-2026-80047 (GHSA-x9r9-c232-4q39): load_custom_generate writes remote code before consent. Affects >=4.49.0,<=5.8.1; no patched version is listed. - CVE-2026-9856 (GHSA-xrqw-3rrv-vx5w): save_pretrained path traversal through chat_template names. Affects <5.10.0. Both researchers independently reproduced CVE-2026-9856 on 5.3.0 (a file written outside the save directory) and saw it rejected on 5.13.0 and 5.18.0. PyPI marks 5.10.0 as yanked, so 5.10.1 (2026-06-03) is the first installable release of that line.

Impact. trainer.py:1730, trainer.py:1749, export.py:184 and merging.py:100 call tokenizer.save_pretrained() on tokenizers loaded from Hub repos (IN-07, TC-U). On 5.3.0-5.9.x, a crafted tokenizer_config.json can write files outside the output directory, which is a path escape (severity hook 1). On 5.3.0-5.4.x, CVE-2026-5241 breaks the stated trust_remote_code=false guarantee (enterprise_deployment.md:152) for a LightGlue-typed repo. CVE-2026-80047 needs custom_generate, which forgelm/ does not call. The top of the range is also broken: on 5.15+ no TRL config can be built (warmup_ratio item), and 5.20 removes the string fsdp form (FSDP item).

Recommendation. Raise the floor to transformers>=5.10.0; pip will resolve 5.10.1 because 5.10.0 is yanked. Point the nightly floor pin (nightly.yml:246) at a non-yanked version. Add a regression test that a traversal chat_template name cannot escape on save, and track the patched version of CVE-2026-80047. Fix the top of the range in the same release: map warmup_ratio and migrate to FSDP2, or add a temporary cap until those land.

Sources.

DOC-D2B06-007 — docs/guides/enterprise_deployment.md: false claim — Security Checklist: offline: true — 'Prevents any network calls'.

severity High · already tracked: KNOWN-OPEN CLI-04 (inferred) — docs/roadmap/phase-16-trust-surface-hardening.md:483-489

Where. docs/guides/enterprise_deployment.md:155 · type: false claim

The document says. Security Checklist: offline: true — 'Prevents any network calls'.

What the code does. offline only sets HF_HUB_OFFLINE / TRANSFORMERS_OFFLINE / HF_DATASETS_OFFLINE and skips HF authentication. Webhook POSTs (url / url_env), the LLM-judge API, the synthetic-data API teacher and experiment trackers (report_to: wandb / mlflow) are not gated by it. The guide's own production template sets report_to: wandb and a webhook.

Code references. forgelm/cli/_config_load.py:50-57, forgelm/config.py:268-271, forgelm/webhook.py:69-83, forgelm/trainer.py:519

User impact. Operators relying on offline mode as an egress control still send run metadata to webhooks, trackers and judge APIs.

Proposed correction. Write: 'Blocks Hugging Face Hub network calls (sets HF_HUB_OFFLINE/TRANSFORMERS_OFFLINE/HF_DATASETS_OFFLINE). It does NOT stop webhooks, judge/teacher APIs or W&B/MLflow: disable those (or set report_to: none) for a true air gap.'

Acceptance criteria

  • A regression test reproduces the failure scenario and asserts the corrected behaviour.
  • Documentation listed above is corrected in English and in its Turkish mirror in the same PR.
  • Every finding in this issue is resolved or explicitly closed with a reason.
  • The release note names the contract this fix restores.

Found by the October 2026 ForgeLM code and documentation review against commit cab2947. Code links point at that commit; line numbers may have moved since. Finding IDs (CR-…, DOC-…, TECH-…) are stable references for this backlog.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: packaging-ciCode area: packaging-cibacklog: knownAlready tracked in docs/roadmapbugSomething isn't workingdependenciesDependency or ecosystem currencydocumentationImprovements or additions to documentationsecuritySecurity-relevantseverity: highWrong behaviour or a false claim users rely onsource: review-2026-10Found by the October 2026 code and documentation reviewurgency: nowTechnology currency: act nowwave: 0Roadmap wave 0: immediate (patch release)

    Type

    No type

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions