| Título | Linketic / CityGaussian CityGaussian up to CityGaussian_V2.0 (main commit 3c1e93b38712334877ff3cfdf724e4ec7ee3e65b) Code Injection (CWE-94) |
|---|
| Descrição | A vulnerability was found in CityGaussian up to CityGaussian_V2.0 (main commit
3c1e93b38712334877ff3cfdf724e4ec7ee3e65b) and classified as high 7.8. Affected is the
cfg_args sidecar parsing component. The manipulation of the argument cfg_args file content
leads to code injection. The attack is launched locally: the victim has to run the documented
mesh extraction command on, or open in the viewer, an attacker-supplied model directory.
Technical Details
- Affected file/function:
V2/main: internal/entrypoints/gs2d_mesh_extraction.py:68 (main(), cfg_args = eval(f.read())).
V2/main: internal/utils/common.py:7 (parse_cfg_args(), return eval(cfg_args)), reached from
internal/renderers/vanilla_deformable_renderer.py:21 and :36-37, and from
internal/renderers/vanilla_gs4d_renderer.py:28.
V1: arguments/__init__.py:105 (get_combined_args(), args_cfgfile = eval(cfgfile_string)).
Verified in releases CityGaussian_V1.0 (8bc816edead74ffb8586ad7f421a40859bde1155),
V1.1 (215dfd3e9a9e75279d4345780af6c4efdda04877), V1.2 (fa111ff89003485be9fa35acc1bf4184169941a9),
V1.5 (eab0dbd0ad5e928b3cb8c8b8a3d07adc6e171ece) and V2.0
(1c0759eece7f428caa65a86f4ca8dd76749bce87); the current default branch is affected as well.
- Vulnerable parameter: the full text of the cfg_args file inside a shared trained model directory
- Attack vector: Local
- Privileges required: None
- Trigger condition: the training pipeline writes a Python expression to <output>/cfg_args
(internal/dataset.py:469-472, "Namespace(sh_degree=..., source_path='...', ...)"), and that
file travels with the trained model directory, which is how 3DGS scenes are distributed. The
consuming side parses it with an unrestricted eval() - there is no ast.literal_eval, no
allowlist and no provenance check on any path. Both documented user workflows reach the sink:
"python utils/gs2d_mesh_extraction.py <model_dir>" (the eval fires before the ply is read, and
this entry never calls torch.load), and opening a third-party-trained model in the viewer with
--vanilla_deformable or --vanilla_gs4d (the eval fires before the deformation checkpoint is
loaded via torch.load). The mesh-extraction path additionally requires no special flag.
- Origin of the weakness: the pattern is inherited from the 3DGS ecosystem (graphdeco-inria
gaussian-splatting lineage and derivatives); the same weakness was already identified and
hardened in another project (see Countermeasure).
Impact
- Confidentiality: High (arbitrary file read with the privileges of the loading process)
- Integrity: High (arbitrary file write and arbitrary code execution in the loading process)
- Availability: High (the process can be terminated or blocked at will)
CVSS v3.1
Score: 7.8 (High)
Vector: CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Timeline
- Discovered: 2026-09-20
- Vendor notified: 2026-09-24 (issue 206 opened; mechanism only, no payload attached)
- Patch released: [pending]
- Public disclosure: 2026-09-24 (issue 206 published; exploit not released)
Countermeasure
Replace eval() with a literal-only parse of the Namespace(...) form: ast.parse the text, accept
only a Namespace call and ast.literal_eval each keyword value. A public precedent for exactly
this hardening is https://github.com/ognjhunt/BlueprintCapturePipeline/pull/22 (merged
2026-03-07). Until a fix is released, only run mesh extraction or the viewer on model
directories from trusted sources. |
|---|
| Fonte | ⚠️ https://github.com/Linketic/CityGaussian/issues/206 |
|---|
| Utilizador | dem0000 (UID 98390) |
|---|
| Submissão | 24/09/2026 14h12 (há 1 mês) |
|---|
| Moderação | 11/10/2026 20h39 (17 days later) |
|---|
| Estado | Aceite |
|---|
| Entrada VulDB | 416766 [Linketic CityGaussian até 2.0 Sidecar Parsing internal/utils/common.py parse_cfg_args Elevação de Privilégios] |
|---|
| Pontos | 20 |
|---|