PowerShell, Get-LiveJournal: параметры скрипта, ч.2 (пароль)

Mar 14, 2023 03:29

Начало: « 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». Поэтому в различных руководствах, которые не успели обновиться, его описание может быть опущено.

Думаю, понятно, для чего используется прикрытие ввода символами-звездочками: чтобы люди, присутствующие рядом с пользователем скрипта при вводе пароля, не могли узнать пароль. (Специалисты по безопасности знают, что очень часто пароль уходит к злоумышленникам через людей, которых жертва взлома считает самыми близкими.)

Продолжение следует...

Инструмент, Образование, Программирование, Английский язык

Previous post Next post
Up