Azure / Azure/azure-sdk-for-python

[Azure.Identity] Add symlink-aware validation to Azure Arc key file path checks

Open
#47,323 0 comments 0 reactions 1 assignee Claimed by @kashifkhan View on GitHub
Azure.Identity
Dominant language
Python
Stars
5.6k
Forks
3.4k
Avg merge
1d 21h
Merged PRs (30d)
193

Description

### Summary

The `_validate_key_file` helper in `azure/identity/_credentials/azure_arc.py` validates the key file path returned by the HIMDS `WWW-Authenticate` header before reading it. The current checks are purely lexical and do not account for symbolic links. Adding symlink resolution would strengthen defense-in-depth.

### Current behavior

`_validate_key_file` performs the following checks on the raw `file_path` string:

1. `os.path.exists(file_path)` -- confirms the path exists.
2. `os.path.dirname(file_path) == _get_key_file_path()` -- lexical comparison of the parent directory.
3. `file_path.endswith(".key")` -- extension check.
4. `os.path.getsize(file_path) <= 4096` -- size cap.

Because step 2 compares the **unresolved** path, a symbolic link such as `/var/opt/azcmagent/tokens/malicious.key -> /etc/shadow` would pass all four checks despite the real target residing outside the trusted directory.

### Proposed enhancement

Before performing the directory comparison, resolve the path to its canonical form:

```python
resolved = os.path.realpath(file_path)
```

Then validate the **resolved** path:

```python
expected_directory = _get_key_file_path()
if os.path.dirname(resolved) != expected_directory:
raise ValueError(f"Unexpected file path from HIMDS service: {file_path}")
```

Additionally, consider checking via `os.lstat` that the file is a regular file (not a symlink, device node, FIFO, etc.):

```python
import stat

file_stat = os.lstat(file_path)
if stat.S_ISLNK(file_stat.st_mode):
raise ValueError("Key file must not be a symbolic link.")
if not stat.S_ISREG(file_stat.st_mode):
raise ValueError("Key file must be a regular file.")
```

### Risk assessment

This is **not** a remotely exploitable vulnerability. Exploitation requires:

- Local filesystem access with sufficient privileges to create a symlink in the trusted directory (`/var/opt/azcmagent/tokens` on Linux or the `PROGRAMDATA\AzureConnectedMachineAgent\Tokens` directory on Windows).
- These directories are already restricted to privileged accounts by the Azure Connected Machine Agent installer.

The enhancement is proposed as **defense-in-depth** to reduce risk in scenarios where directory permissions are inadvertently relaxed or an attacker has partial local access.

### Affected file

- [`sdk/identity/azure-identity/azure/identity/_credentials/azure_arc.py`](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/identity/azure-identity/azure/identity/_credentials/azure_arc.py) -- `_validate_key_file` function.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.