Я ищу (1) самый безопасный и (2) самый простой способ, чтобы пользователь вводил пароль в командной строке bash и чтобы этот пароль стал частью стандартного ввода программы.
Вот как должен выглядеть stdin: {"username":"myname","password":"<my-password>"}
где <my-password>
то, что было напечатано в приглашении оболочки. Если бы у меня был контроль над программой stdin, то я мог бы изменить ее, чтобы безопасно запросить пароль и поставить его на место, но последующий поток - это стандартная команда общего назначения.
Я рассмотрел и отклонил подходы, которые используют следующее:
- пользователь вводит пароль в командной строке: пароль будет отображаться на экране, а также будет виден всем пользователям через «ps»
- интерполяция переменной оболочки в аргумент внешней программы (например,
...$PASSWORD...
): пароль все равно будет виден всем пользователям через «ps» - переменные среды (если они оставлены в среде): пароль будет виден всем дочерним процессам; даже заслуживающие доверия процессы могут раскрыть пароль, если они сбрасывают ядро или переменные среды как часть диагностики
- пароль хранится в файле в течение длительного периода времени, даже в файле с жесткими разрешениями: пользователь может случайно раскрыть пароль, а пользователь root может случайно увидеть пароль
Я приведу свое текущее решение в качестве ответа ниже, но с радостью выберу лучший ответ, если кто-то придет к нему. Я думаю, что должно быть что-то более простое, или, возможно, кто-то видит проблему безопасности, которую я пропустил.
Ответы:
С
bash
илиzsh
:Без
IFS=
,read
удалит начальные и конечные пробелы из введенного вами пароля.Без
-r
этого он будет обрабатывать обратную косую черту как символ цитирования.Вы хотите убедиться, что вы только когда-либо читали из терминала.
echo
не может быть надежно использован. Вbash
иzsh
,printf
является встроенным , так что командная строка не будет показывать на выходеps
.В
bash
, вам нужно заключить$password
в кавычки, так как в противном случае к нему применяется оператор split + glob .Это все еще неправильно, хотя вам нужно закодировать эту строку как JSON. Например, двойная кавычка и обратный слэш по крайней мере будут проблемой. Возможно, вам нужно беспокоиться о кодировке этих символов. Ваша программа ожидает строки UTF-8? Что отправляет ваш терминал?
Чтобы добавить строку приглашения, с помощью
zsh
:С
bash
:источник
unset password
иset +a
там, но это можно пропустить, если вы можете сделать больше предположений о текущей оболочке. Хорошее замечание по поводу опции -r, чтобы читать и ставитьIFS=
перед ней для лучшей универсальности с различными паролями. Хорошо перейти из / dev / tty для принудительного ввода с терминала.python3 -c 'import json; print(json.dumps({"username": "myname", "password": input()}))'
, если у вас есть Python валяется. Для Python 2, s / input / raw_input /. Если вы передадите пароль в эту команду, он выдаст соответствующий JSON.Вот решение, которое у меня есть (оно было проверено):
Объяснение:
read -s
читает строку ввода (пароль), не отображая строку на экране. Он хранится в переменной оболочки PASSWORD.echo -n $PASSWORD
ставит пароль на стандартный вывод без перевода строки. (echo - встроенная команда оболочки, поэтому новый процесс не создается, поэтому (AFAIK) пароль в качестве аргумента для echo не будет показан на ps.)$_
$_
полный текст и выводит его на стандартный выводЕсли это происходит в HTTPS POST, вторая строка будет выглядеть примерно так:
источник
printf '{"username":"myname","password":"%s"}' $PASSWORD
, которое сохраняет те же свойства безопасности и сохраняет вам внешний процесс.read
команд, которые не поддерживают флаг -s, вы можете использовать "stty -echo; читать PASSWORD; stty echo"perl -e '...' <<< "$PASSWORD"
.<<<
вbash
магазинах содержимое во временный файл , который хуже.Если ваша версия
read
не поддерживает-s
, попробуйте POSIX-совместимый способ, описанный в этом ответе .set +a
Должен предотвратить автоматический «экспорт» переменной в окружающую среду. Вы должны проверить справочные страницы дляstty
, есть много доступных вариантов. Это<<<"$passwd"
указано, потому что хорошие пароли могут иметь пробелы. Последнимecho
после включенияstty echo
является начало следующей команды / вывода с новой строки.источник