3

I am reviewing a web application which exposes a functionality for the user to change his unix password via a web interface. An authenticated web user gives his unix username and his desired password. Command injection is an obvious attack vector here.

The input is validated and sanitized by mandating usernames to be only in:
/^[a-zA-Z0-9]+$/

Thereafter it does something like (in python):

p = os.popen("/usr/bin/passwd " + username, "w")

and so on and so forth.

If they didn't have that regex, a username like jon; rm -rf would be catastrophic for system or popen.

I wan't something more fundamental that won't allow me to harm myself even if bad input like that makes way to the system/popen call. (For eg. subprocess )

Is there a more secure way of doing this or validation of input remains to be the only defense ? I was looking for something safer than system/popen or a different approach altogether if there is a standard way of executing commands where part of command comes from a user input.

CodeExpress
  • 2,202
  • 1
  • 20
  • 16
  • Doing it the regex way is standard stuff, building a complete sandbox is a __LOT__ more work. – orlp Feb 20 '12 at 17:57
  • @nightcracker: No, doing it the regex way is not standard stuff in that case. Using the right module is the standard stuff. – Niklas B. Feb 20 '12 at 17:59
  • 1
    +1 for wanting to do it the right way. Somebody posts blatantly injection-vulnerable code on SO at least once a day. – Jim Garrison Feb 20 '12 at 18:00

2 Answers2

3

You could quote the input yourself:

import pipes
p = os.popen("/usr/bin/passwd " + pipes.quote(username), 'w')

os.popen is however deprecated and pipes.quote is an undocumented function, so you'd be much better off just using the subprocess module:

import subprocess
p = subprocess.Popen(["/usr/bin/passwd", username])
Niklas B.
  • 92,950
  • 18
  • 194
  • 224
0

To avoid code injection, use the API's correctly.

http://atlee.ca/software/pam/

http://ace-host.stuart.id.au/russell/files/pam_python/

Security concerns with a Python PAM module?

Community
  • 1
  • 1
S.Lott
  • 384,516
  • 81
  • 508
  • 779