Repository navigation
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
Description
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.
pyproject.toml:53forgelm/model.py:390forgelm/trainer.py:1730and :1749 (tokenizer.save_pretrained in save_final_model, defined at :1711 and called at :1542, :1612, :1620)forgelm/trainer.py:1749forgelm/export.py:172(load) and :184 (save) in _merge_adapter, reached from export_model at :430forgelm/merging.py:100.github/workflows/nightly.yml:239-246(comment and pin transformers==5.3.0).github/workflows/nightly.yml:246tools/pip_audit_ignores.yaml:35-41docs/guides/enterprise_deployment.md:152
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.
- NVD CVE-2026-4372 (2026-07-23)
- GHSA-29pf-2h5f-8g72 (CVE-2026-4372) first patched 5.3.0 (2026-07-01)
- GHSA-xrqw-3rrv-vx5w (CVE-2026-9856) first patched 5.10.0 (2026-09-01)
- GHSA-fgcw-684q-jj6r (CVE-2026-5241) first patched 5.5.0 (2026-07-21)
- GHSA-x9r9-c232-4q39 (CVE-2026-80047) >=4.49.0,<=5.8.1, no patched version (2026-09-30)
- NVD CVE-2026-9856 (2026-09-03)
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
Labels
Type
Projects
- StatusShow more project fieldsTodo
Activity
docs(deps): name the test file that really compares the nightly pins
fix: rope_scaling on transformers 5, hub telemetry, reserved retentio…