T03 · Remote Payload Retrieval and Execution
Error
- Location
- scripts/meeting_to_text.py:175
- Finding
- Remote Model Download Followed by Unsafe PyTorch Deserialization<![CDATA[ ## Vulnerability Details **File Location**: `scripts/meeting_to_text.py:175-186` and `scripts/meeting_to_text.py:215-224` **Vulnerability Type**: Remote payload retrieval, insecure dependency handling, and unsafe model deserialization **Risk Level**: High ### Complete Vulnerable Code ```python def ensure_speaker_model_cached() -> Path: target_dir = THREE_D_SPEAKER_CACHE / SPEAKER_MODEL_ID if (target_dir / "configuration.json").exists(): return target_dir THREE_D_SPEAKER_CACHE.mkdir(parents=True, exist_ok=True) from modelscope.hub.snapshot_download import snapshot_download downloaded = snapshot_download( SPEAKER_MODEL_ID, revision=SPEAKER_MODEL_REVISION, cache_dir=str(THREE_D_SPEAKER_CACHE), ) return Path(downloaded) ``` The downloaded checkpoint is subsequently loaded as follows: ```python model_dir = ensure_speaker_model_cached() checkpoint_path = model_dir / SPEAKER_MODEL_CKPT if not checkpoint_path.exists(): raise DiarizationError(f"Missing speaker model checkpoint: {checkpoint_path}") config = Config( { "feature_extractor": { "obj": "speakerlab.process.processor.FBank", "args": { "n_mels": 80, "sample_rate": SAMPLE_RATE, "mean_nor": True, }, }, "embedding_model": { "obj": "speakerlab.models.campplus.DTDNN.CAMPPlus", "args": { "feat_dim": 80, "embedding_size": 192, }, }, } ) feature_extractor = build("feature_extractor", config) embedding_model = build("embedding_model", config) state_dict = torch.load(str(checkpoint_path), map_location="cpu") embedding_model.load_state_dict(state_dict) embedding_model.eval() ``` ### Technical Analysis When the speaker model is not already cac ...[truncated 2893 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Fail closed when the local model is missing** - Package or provision the approved speaker model separately. - Remove automatic runtime downloading from the transcription path. - Return a clear validation error if the required model is unavailable. 2. **Use a non-executable model format** - Prefer SafeTensors or another format that stores tensors without pickle-based object deserialization. - Convert and validate the expected model weights during a controlled build or provisioning process. 3. **Restrict PyTorch loading** - Where supported, use: ```python state_dict = torch.load( str(checkpoint_path), map_location="cpu", weights_only=True, ) ``` - Confirm that the returned object is a plain state dictionary containing only expected tensor keys and value types. - Reject unexpected objects, missing keys, extra keys, or incompatible tensor shapes. 4. **Verify artifact integrity** - Pin an approved model version and expected SHA-256 digest in trusted project configuration. - Calculate the checkpoint digest before loading it and reject any mismatch. - Prefer publisher signatures or a trusted internal artifact repository in addition to checksum verification. 5. **Protect the local cache** - Store models in a directory writable only by trusted administrators or the dedicated application account. - Reject symlinks and verify that the resolved checkpoint remains under the approved model directory. - Avoid sharing a writable model cache between mutually untrusted users. 6. **Disclose network behavior** - If remote download remains necessary, update `SKILL.md` to state that a cache miss causes network access. - Require explicit user authorization before downloading. - Restrict outbound access to the approved endpoint and apply download size and timeout limits. 7. **Separate acquisition from execution** - Implement a controlled inst ...[truncated 171 chars]
