1

I have a function that takes a pathname and substitutes every occurrence of '%u' with a given String. For my scenario this given String is the login that a user/attacker enters via ssh during authentication. The pathname (including the '%u') is fixed and cannot be changed by the user/attacker.

Lets say the fixed pathname is:

/usr/local/etc/ssh/keystore/%u/authorized_keys

If the user/attacker e.g. is now issuing the following command:

ssh [email protected]

The path will be extended to:

/usr/local/etc/ssh/keystore/root/authorized_keys

If user root is now authorized (will be determined by ldap group membership) and has a valid x509 certificate the public key of the x509 certificate will be written into the examined authorized_keys file. If the user is not authorized the authorized_keys file will be truncated.

An attacker is now able to truncate every existing authorized_keys file on the filesystem due to the fact that no input validation takes place for the given user login.

Consider the following ssh connect:

ssh ../keystore/[email protected]

The path will be extended to:

/usr/local/etc/ssh/keystore/../keystore/foo/authorized_keys

With quite a high probability the user '../keystore/foo' is not authorized to log in to the system leading to the truncation of the authorized_keys file of a possibly legal user 'foo'.

Although during the next connect of foo his authorized_keys file gets updated again I wanna get rid of this attack vector.

So far two possible solutions came into my mind:


1. Validate user login against a regular expression (whitelist approach)

E.g. use the default NAME_REGEX:

^[a-z][-a-z0-9]*\$

Still if the system does not use the NAME_REGEX functionality users would be closed out from ssh

2. Check if expanded path contains '..' and fail if so (blacklist approach)

This wouldn't close out users but still I am not quite sure if this is sufficient or if any other patterns exists that could lead to the same behavior as mentioned above


3
  • I've edited your question since apparently you are actually not dealing with the users's UID (which is the numeric user ID) but rather the user's login. Would my understanding be wrong, feel free to click on the "edited" link above which will offer you the possibility to "rollback" my modifications. May 16, 2015 at 12:56
  • 1
    “If the user is not authorized the authorized_keys file will be truncated.” So any login with incorrect credentials but a valid user name disables the account? That's bizarre. What could motivate such a huge built-in denial of service? May 16, 2015 at 13:50
  • No. Authorized means that the user has the appropriate group membership for that OpenSSH server in the LDAP server. If so the key of the x509 certificate will be synchronized else the authorized_keys file will be trunacted. If you try to login with a valid and authorized user name but dont posses the corresponding private key you simply cannot login. For that case there wont be any truncation of the authorized_keys file.
    – fliX
    May 16, 2015 at 13:59

1 Answer 1

1

There is no doubt that the white-list approach remains the best one (actually I would even add a maximum size limitation to this regex, I guess a legitimate login counting several hundreds of characters should not be so frequent...), because it will protect you also against a range of unsuspected exploits and brings you some level of trust that the login passing this tests, whether valid or not, are correctly formed and will not have the possibility to harm the system.

Having user names to comply with some reasonable pattern does not seem an excessive requirement (Have you ever tried an account like "foo' or '1' ='1" somewhere? Or claimed that your really need unicode or non-standard charset support for your favorite login?).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .