#python #linux #unix #passwords
#python #linux #unix #пароли
Вопрос:
Рассмотрим учетную запись UNIX jdoe
. Я хочу обновить jdoe
пароль, используя скрипт Python, запущенный как root
. В настоящее время я использую:
cmd = 'echo "' username ":" new_pass '" | chpasswd '
os.system(cmd)
Однако это небезопасный метод. Если бы кто-то вошел new_pass
как pass"; rm -rf / #
, это было бы катастрофой.
Есть ли безопасный способ сделать это?
Ответ №1:
Если вас беспокоит ненадежный ввод, лучше избегать использования os.system
, поскольку это вызывает оболочку, и, в общем, вы не хотите, чтобы оболочка находилась рядом с ненадежным вводом. Кроме того, вы обычно хотите избежать ввода секретов в аргументы командной строки, поскольку они могут быть прочитаны другими пользователями, хотя, поскольку echo
это обычно встроено, это не является строго проблемой здесь.
Чтобы сделать это безопасно, вы можете использовать subprocess.Popen
вместо этого, вот так:
import subprocess
proc = subprocess.Popen(['chpasswd'], stdin=subprocess.PIPE)
proc.stdin.write(b"username:password")
Обратите внимание, что если вам нужно передать дополнительные аргументы chpasswd
, вы бы сделали это, добавив аргументы в массив:
proc = subprocess.Popen(['chpasswd', '-c', 'SHA512'], stdin=subprocess.PIPE)
Комментарии:
1. Похоже, это работает с
new_pass = pass"; rm -rf / #
. Надеюсь, я ничего не упускаю из виду.2. Он действительно должен работать с произвольным паролем, включая пароль, содержащий внедрение оболочки. В этом случае это всего лишь часть пароля, а не уязвимость системы безопасности.
3. Удивительно, но это не работает с flask, я не могу понять, почему.
4. Ах, замена
proc.stdin.write(...)
наproc.communicate(input=...)
исправила проблему.
Ответ №2:
Я бы изменил его так, чтобы введенный пароль был хэширован (sha512 является стандартным в современных системах Linux), а затем передал значение хэшей в ваш cmd.
cmd = 'echo "' username ":" new_pass '" | chpasswd -e'
os.system(cmd)
Обратите внимание на -e
после chpasswd
Уточняем приведенное выше предложение немного подробнее:
import crypt
entered_password = 'pass"; rm -rf / #'
new_password = crypt.crypt(entered_password, '$6$' 'salt1234')
Комментарии:
1. Я делаю
cmd = 'echo "' username ":" sha512(new_pass) '" | chpasswd -e'
,os.system(cmd)
но когда я пытаюсь войти в систему,new_pass
это недопустимо. Для чего используется хэш по умолчаниюchpasswd -e
? Похоже, что это не sha256.