Начало: «
PowerShell, Get-LiveJournal: параметры скрипта, ч.1 (param и $args)».
Окружение: операционная система «Windows 10», программа-оболочка «PowerShell» версии 7, скрипт «
Get-LiveJournal».
Получение пароля от пользователя скрипта
Как оказалось, передача пароля в скрипт в открытом виде через текстовый параметр не одобряется. Считается плохой практикой в программировании на языке PowerShell. Такая операция считается небезопасной.
Например, программы-оболочки обычно сохраняют некоторое количество недавно введенных команд в стеке, который называют «историей введения команд». История введения команд делает работу в программе-оболочке очень удобной: если требуется снова ввести команду, которая была использована недавно (такое бывает довольно часто в работе), достаточно быстро пролистать историю и выбрать эту команду оттуда, а не вводить ее заново. Пользование историей введения команд очень сильно ускоряет работу в программе-оболочке. Однако, если вы прямо ввели в команде пароль, то злоумышленник сможет легко извлечь этот пароль из истории введения команд (конечно, предварительно ему понадобится как-то получить доступ к вашей программе-оболочке).
Кстати, есть хорошее руководство по стилю программирования на языке PowerShell - «
Powershell Practice and Style», в нем есть
глава о передаче пароля в скрипт через параметры. Однако, в первый раз об изложенном там я узнал не из этого руководства, а при написании скрипта в редакторе «VS Code».
Сначала я написал что-то вроде следующего:
скрипт «test.ps1»
param($user, $password)
В моем экземпляре редактора «VS Code» установлено расширение для работы с языком PowerShell (
тут подробнее). Это расширение включает в себя линтер (статический анализатор кода) «
PSScriptAnalyzer», который работает сразу же после установки расширения для работы с языком PowerShell. Этот линтер сразу же, по умолчанию, включает в себя набор правил, нет необходимости писать эти правила с нуля. Линтер проанализировал код, приведенный в блоке выше, и выдал предупреждение:
На иллюстрации выше видно, что сомнительный код подчеркивается желтой волнистой линией. Это не является ошибкой (ошибки подчеркиваются красной волнистой линией) с точки зрения синтаксиса, но так не рекомендуется делать с точки зрения безопасности. Хотя вы, конечно, можете проигнорировать такие предупреждения. Также отметка о предупреждениях появляется сверху, в названии файла, открытого в редакторе (название меняет цвет с белого на желтый; рядом с названием появляется число предупреждений), а также в строке состояния в левом нижнем углу и справа, на вертикальном ползунке (строка с предупреждением отмечается желтой отметкой).
Как видно на иллюстрации выше, при наведении указателя мыши на подчеркнутый код появляется дополнительное окно с подробным описанием проблемы. В этом же описании есть рекомендации по исправлению проблемы. В данном случае мне было порекомендовано вместо параметра класса «
System.String» использовать либо параметр класса «
System.Security.SecureString», либо параметр класса «
System.Management.Automation.PSCredential».
Я понимаю, что из себя представляют предложенные классы, но не понимаю, как должна выглядеть работа с ними. То, как в интернетах предлагают использовать эти классы, выглядит громоздко и неудобно ни для пользователя, ни для программиста. Возможно, я чего-то не знаю или не понимаю. В итоге я выбрал третий вариант, я написал так:
скрипт «test.ps1»
param($user)
$password = Read-Host "Введите пароль пользователя `"$user`"" -MaskInput
запускаем скрипт из программы-оболочки:
PS C:\> .\test "ilyachalov"
Введите пароль пользователя "ilyachalov": *********
То есть я вообще убрал пароль из параметров скрипта. Теперь скрипт запрашивает пароль только после своего запуска. Таким образом, в истории введенных команд пароль не останется и злоумышленник не сможет извлечь пароль из истории введенных команд. Такой порядок работы, конечно, менее удобен для пользователя скрипта, чем открытая передача пароля через строковый параметр, но он безопаснее с точки зрения защиты пароля от злоумышленника.
Для запрашивания данных от пользователя скриптом обычно используют командлет «
Read-Host». По умолчанию вводимые пользователем буквы не скрываются, но я использовал параметр -MaskInput для прикрытия вводимых букв символами-звездочками. Этот параметр добавлен к этому командлету относительно недавно (17 августа 2020 года), с версии 7.1 программы-оболочки «PowerShell». Поэтому в различных руководствах, которые не успели обновиться, его описание может быть опущено.
Думаю, понятно, для чего используется прикрытие ввода символами-звездочками: чтобы люди, присутствующие рядом с пользователем скрипта при вводе пароля, не могли узнать пароль. (Специалисты по безопасности знают, что очень часто пароль уходит к злоумышленникам через людей, которых жертва взлома считает самыми близкими.)
Продолжение следует...