T05 · Unauthorized Access and Privilege Escalation
Error
- Location
- attestation_system_v3.py:54
- Finding
- Agent Name Allows Key-File Path Traversal and Arbitrary File Overwrite<![CDATA[ ## Vulnerability Details **File Location**: `attestation_system_v3.py:54-62, 76-96` **Vulnerability Type**: Path traversal and unsafe file access **Risk Level**: High ### Vulnerable Code ```python # Save to files private_path = self.keys_dir / f"{agent_name}.key" public_path = self.keys_dir / f"{agent_name}.pub" with open(private_path, 'wb') as f: f.write(private_pem) with open(public_path, 'wb') as f: f.write(public_pem) ``` The same unsanitized value is used when loading keys: ```python def load_private_key(self, agent_name: str) -> Optional[ed25519.Ed25519PrivateKey]: """Load private key from file.""" private_path = self.keys_dir / f"{agent_name}.key" if not private_path.exists(): return None with open(private_path, 'rb') as f: private_pem = f.read() return serialization.load_pem_private_key( private_pem, password=None, backend=default_backend() ) def load_public_key(self, agent_name: str) -> Optional[ed25519.Ed25519PublicKey]: """Load public key from file.""" public_path = self.keys_dir / f"{agent_name}.pub" if not public_path.exists(): return None with open(public_path, 'rb') as f: public_pem = f.read() return serialization.load_pem_public_key( public_pem, backend=default_backend() ) ``` ### Technical Analysis `agent_name` is incorporated directly into private- and public-key paths without validation. A value containing `../` can escape `keys_dir`, while an absolute path causes `pathlib` to disregard the configured base directory. The code also follows filesystem symbolic links. When the computed key pair does not already exist, object initialization generates a new pair and writes both files using `wb`, which truncates existing writable files. If both attacker-selected files already exist and contain valid PEM keys, the loading path can instead cause the application to consume keys outside the intended ke ...[truncated 1607 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Validate `agent_name` against a strict identifier allowlist, such as `^[A-Za-z0-9_-]{1,64}$`. - Reject absolute paths, path separators, null bytes, `.` components, and `..` components. - Prefer deriving filenames from a full cryptographic hash of the logical agent identifier. - Resolve the resulting path and verify that it remains under the resolved key directory before every read or write. - Reject symbolic-link targets and use safe file-opening flags such as `O_NOFOLLOW` where supported. - Create new key files atomically with exclusive creation rather than truncating existing files. - Separate logical identity names from physical key-store filenames. ]]>
