Есть старое правило: если можно сделать быстро и удобно, кто‑то обязательно сделает это в ущерб безопасности. В инфраструктурных командах это особенно заметно. Сетевики часто решают задачи «с лёту», и это прекрасно. Пока речь не заходит про пароли. Один из таких случаев стал для нас уроком На первый взгляд — мелочь, но последствия могли быть куда серьёзнее.
Как всё началось
Обычный рабочий день. Я проверял список процессов на сервере (ps aux) и вдруг вижу:
bash
sshpass -p 'Qwerty123' ssh admin@10.0.5.21
Пароль. В открытом виде. В командной строке.
Подошёл к коллеге:
— Это что за магия?
— Скрипт для быстрого доступа, чтобы пароль не вводить каждый раз.
— Ты в курсе, что этот пароль может увидеть любой пользователь на сервере?
— Ну мы же внутри сети
— До первого
psили попадания в логи.
Через пару часов у нас уже был внеплановый аудит.
Почему это проблема:
Передача пароля в аргументах — это классический антипаттерн.
-
Аргументы команд видны в
ps,/proc/[PID]/cmdline, Task Manager. -
Они могут попасть в логи CI/CD.
-
Мониторинг и аудит тоже их подхватят.
-
Многие утилиты (
sshpass,plink,WinSCP CLI,rsync,mysql,curl,mRemoteNG) позволяют так передавать пароль — и это соблазн для быстрого «костыля».
В итоге получить пароль можно, даже не трогая сам SSH.
Как искать такие случаи
Windows (PowerShell)
powershell
$insecureProcs = Get-CimInstance Win32_Process | Where-Object {
$_.CommandLine -match '-ps' -or $_.CommandLine -match '-pws' -or $_.CommandLine -match '--password=' -or $_.CommandLine -match '/password='
} | Select-Object ProcessId, Name, CommandLine
$insecureProcs | Format-Table -AutoSize
Linux (bash)
bash
ps -eo pid,user,command --no-header | while read PID USER CMD; do
if [[ "$CMD" =~ -p ]] || [[ "$CMD" =~ -pw ]] || [[ "$CMD" =~ --password= ]] || [[ "$CMD" =~ /password= ]]; then
echo "PID=$PID USER=$USER CMD=$CMD"
fi
done
Как мы «засветили» пароль в проде
Оказалось, что у нас крутился ночной бэкап через cron с командой:
bash
sshpass -p 'MySecret123' ssh backup@10.1.1.25
На сервере работали и другие пользователи. Пароль всплыл в мониторинге процессов.
В довесок Jenkins сохранил эту же команду в логи пайплайна, доступные всем участникам проекта. Пришлось срочно менять ключи, чистить задачи и усиливать контроль.
Мини-справочник уязвимых инструментов
|
Инструмент |
Параметр пароля |
Где светится |
|
sshpass |
-p |
ps, /proc |
|
plink / pscp |
-pw |
Task Manager |
|
WinSCP CLI |
/password= |
cmdline |
|
rsync |
--password-file |
при доступном файле |
|
curl / wget |
http://user:pass@ |
аргументы |
|
mysql |
--password= |
предупреждение |
|
smbclient |
user%pass |
ps |
|
Jenkins |
sh "sshpass..." |
логи |
Что внедрить в процесс
Linux — cron‑сканеры, Ansible, shell‑скрипты.
Windows — PowerShell + логирование.
CI/CD — линтеры и сканеры (Checkov, KICS, Semgrep).
IDE — pre‑commit хуки, запрещающие команды с паролем в аргументах.
Пример правила для Semgrep:
yaml
pattern: sshpass -p $PASS ...
message: 'Пароль передается в командной строке — это небезопасно.'
severity: ERROR
Как делать безопасно:
-
Использовать
ssh-agentи ключи без паролей в скриптах. -
Хранить секреты в Vault, AWS Secrets Manager, Ansible Vault.
-
Прятать учётки в
.pgpass,.my.cnf,.netrc(права 600). -
Разграничивать доступ: никто кроме root не должен видеть чужие процессы.
-
Ограничивать или удалять опасные утилиты (
sshpassи пр.). -
В случаях когда необходимо хранить секреты в файлах использовать кодировку
Вывод
Одна невинная оптимизация могла обернуться утечкой. Мы нашли и закрыли дыру, добавили регулярные проверки, а коллега перешёл на ключи.
Совет: проверьте свои сервера прямо сейчас. Если пароли в аргументах есть — убирайте немедленно. Такие мелочи могут стоить гораздо дороже, чем пять минут на настройку.
P. S. Был ли у вас подобный опыт? Расскажите, как находили и закрывали такие дыры. Возможно, получится собрать полезную подборку практик.
Автор: abp2b
