Skip to content

Add symlink and chown checks when accessing key path#2192

Open
norakoiralamsft wants to merge 1 commit into
masterfrom
norakoirala/security-fix
Open

Add symlink and chown checks when accessing key path#2192
norakoiralamsft wants to merge 1 commit into
masterfrom
norakoirala/security-fix

Conversation

@norakoiralamsft

Copy link
Copy Markdown
Contributor

The PR aims to address improper handling of symbolic links in the process of resetting or setting SSH public keys for existing Linux users.

This was the suggested mitigation : Open the target with O_NOFOLLOW (and O_EXCL when creating), or verify with os.lstat/os.path.islink that the final path component is not a symlink immediately before writing. Replace os.chown with os.lchown so ownership changes never follow a symlink. Before operating, validate that the parent .ssh directory and the authorized_keys file are owned by the target user and are not symlinks; refuse otherwise. Apply the same guards to the SSH2/PKCS8 conversion branch (ssh_deploy_public_key).

@norakoiralamsft norakoiralamsft requested review from a team, D1v38om83r and nkuchta as code owners July 1, 2026 17:37
Comment thread VMAccess/vmaccess.py


def validate_ssh_path(pub_path, user_name):
p = pwd.getpwnam(user_name)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this return a nil or err?

Comment thread VMAccess/vmaccess.py
uid = p.pw_uid

ssh_dir = os.path.dirname(pub_path)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly, can this fail?

Comment thread VMAccess/vmaccess.py
raise Exception("Refusing to write: {0} is not owned by {1} or root".format(ssh_dir, user_name))

# Validate authorized_keys is not a symlink and is owned by the target user
if os.path.islink(pub_path):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: could create a helper method since the code above is the same

Comment thread VMAccess/vmaccess.py
# overwrite the default logger
logger.global_shared_context_logger = logger.Logger('/var/log/waagent.log', '/dev/stdout')


Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall comment. unit tests?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants